|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 #include <stdio.h> |
|
6 #include "nsXPCOM.h" |
|
7 #include "nsIComponentManager.h" |
|
8 #include "nsISupports.h" |
|
9 #include "nsServiceManagerUtils.h" |
|
10 #include "nsILineBreaker.h" |
|
11 #include "nsIWordBreaker.h" |
|
12 #include "nsLWBrkCIID.h" |
|
13 #include "nsStringAPI.h" |
|
14 #include "nsEmbedString.h" |
|
15 #include "TestHarness.h" |
|
16 |
|
17 #define WORK_AROUND_SERVICE_MANAGER_ASSERT |
|
18 |
|
19 NS_DEFINE_CID(kLBrkCID, NS_LBRK_CID); |
|
20 NS_DEFINE_CID(kWBrkCID, NS_WBRK_CID); |
|
21 |
|
22 |
|
23 static char teng1[] = |
|
24 // 1 2 3 4 5 6 7 |
|
25 //01234567890123456789012345678901234567890123456789012345678901234567890123456789 |
|
26 "This is a test to test(reasonable) line break. This 0.01123 = 45 x 48."; |
|
27 |
|
28 static uint32_t exp1[] = { |
|
29 4,7,9,14,17,34,39,40,41,42,49,54,62,64,67,69,73 |
|
30 }; |
|
31 |
|
32 static uint32_t wexp1[] = { |
|
33 |
|
34 4,5,7,8,9,10,14,15,17,18,22,23,33,34,35,39,43,48,49,50,54,55,56,57,62,63, |
|
35 64,65,67,68,69,70,72 |
|
36 }; |
|
37 // 1 2 3 4 5 6 7 |
|
38 //01234567890123456789012345678901234567890123456789012345678901234567890123456789 |
|
39 static char teng2[] = |
|
40 "()((reasonab(l)e) line break. .01123=45x48."; |
|
41 |
|
42 static uint32_t lexp2[] = { |
|
43 17,22,23,30,44 |
|
44 }; |
|
45 static uint32_t wexp2[] = { |
|
46 4,12,13,14,15,16,17,18,22,24,29,30,31,32,37,38,43 |
|
47 }; |
|
48 |
|
49 // 1 2 3 4 5 6 7 |
|
50 //01234567890123456789012345678901234567890123456789012345678901234567890123456789 |
|
51 static char teng3[] = |
|
52 "It's a test to test(ronae ) line break...."; |
|
53 static uint32_t exp3[] = { |
|
54 4,6,11,14,25,27,32,42 |
|
55 }; |
|
56 static uint32_t wexp3[] = { |
|
57 2,3,4,5,6,7,11,12,14,15,19,20,25,26,27,28,32,33,38 |
|
58 }; |
|
59 |
|
60 static char ruler1[] = |
|
61 " 1 2 3 4 5 6 7 "; |
|
62 static char ruler2[] = |
|
63 "0123456789012345678901234567890123456789012345678901234567890123456789012"; |
|
64 |
|
65 |
|
66 bool TestASCIILB(nsILineBreaker *lb, |
|
67 const char* in, const uint32_t len, |
|
68 const uint32_t* out, uint32_t outlen) |
|
69 { |
|
70 NS_ConvertASCIItoUTF16 eng1(in); |
|
71 uint32_t i,j; |
|
72 uint32_t res[256]; |
|
73 bool ok = true; |
|
74 int32_t curr; |
|
75 for(i = 0, curr = 0; (curr != NS_LINEBREAKER_NEED_MORE_TEXT) && |
|
76 (i < 256); i++) |
|
77 { |
|
78 curr = lb->Next(eng1.get(), eng1.Length(), curr); |
|
79 res [i] = curr != NS_LINEBREAKER_NEED_MORE_TEXT ? curr : eng1.Length(); |
|
80 |
|
81 } |
|
82 if (i != outlen) |
|
83 { |
|
84 ok = false; |
|
85 printf("WARNING!!! return size wrong, expect %d but got %d \n", |
|
86 outlen, i); |
|
87 } |
|
88 printf("string = \n%s\n", in); |
|
89 printf("%s\n", ruler1); |
|
90 printf("%s\n", ruler2); |
|
91 printf("Expect = \n"); |
|
92 for(j=0;j<outlen;j++) |
|
93 { |
|
94 printf("%d,", out[j]); |
|
95 } |
|
96 printf("\nResult = \n"); |
|
97 for(j=0;j<i;j++) |
|
98 { |
|
99 printf("%d,", res[j]); |
|
100 } |
|
101 printf("\n"); |
|
102 for(j=0;j<i;j++) |
|
103 { |
|
104 if(j < outlen) |
|
105 { |
|
106 if (res[j] != out[j]) |
|
107 { |
|
108 ok = false; |
|
109 printf("[%d] expect %d but got %d\n", j, out[j], res[j]); |
|
110 } |
|
111 } else { |
|
112 ok = false; |
|
113 printf("[%d] additional %d\n", j, res[j]); |
|
114 } |
|
115 } |
|
116 return ok; |
|
117 } |
|
118 |
|
119 bool TestASCIIWB(nsIWordBreaker *lb, |
|
120 const char* in, const uint32_t len, |
|
121 const uint32_t* out, uint32_t outlen) |
|
122 { |
|
123 NS_ConvertASCIItoUTF16 eng1(in); |
|
124 |
|
125 uint32_t i,j; |
|
126 uint32_t res[256]; |
|
127 bool ok = true; |
|
128 int32_t curr = 0; |
|
129 |
|
130 for(i = 0, curr = lb->NextWord(eng1.get(), eng1.Length(), curr); |
|
131 (curr != NS_WORDBREAKER_NEED_MORE_TEXT) && (i < 256); |
|
132 curr = lb->NextWord(eng1.get(), eng1.Length(), curr), i++) |
|
133 { |
|
134 res [i] = curr != NS_WORDBREAKER_NEED_MORE_TEXT ? curr : eng1.Length(); |
|
135 } |
|
136 if (i != outlen) |
|
137 { |
|
138 ok = false; |
|
139 printf("WARNING!!! return size wrong, expect %d but got %d\n", |
|
140 outlen, i); |
|
141 } |
|
142 printf("string = \n%s\n", in); |
|
143 printf("%s\n", ruler1); |
|
144 printf("%s\n", ruler2); |
|
145 printf("Expect = \n"); |
|
146 for(j=0;j<outlen;j++) |
|
147 { |
|
148 printf("%d,", out[j]); |
|
149 } |
|
150 printf("\nResult = \n"); |
|
151 for(j=0;j<i;j++) |
|
152 { |
|
153 printf("%d,", res[j]); |
|
154 } |
|
155 printf("\n"); |
|
156 for(j=0;j<i;j++) |
|
157 { |
|
158 if(j < outlen) |
|
159 { |
|
160 if (res[j] != out[j]) |
|
161 { |
|
162 ok = false; |
|
163 printf("[%d] expect %d but got %d\n", j, out[j], res[j]); |
|
164 } |
|
165 } else { |
|
166 ok = false; |
|
167 printf("[%d] additional %d\n", j, res[j]); |
|
168 } |
|
169 } |
|
170 return ok; |
|
171 } |
|
172 |
|
173 |
|
174 bool TestLineBreaker() |
|
175 { |
|
176 printf("===========================\n"); |
|
177 printf("Finish nsILineBreaker Test \n"); |
|
178 printf("===========================\n"); |
|
179 nsILineBreaker *t = nullptr; |
|
180 nsresult res; |
|
181 bool ok = true; |
|
182 res = CallGetService(kLBrkCID, &t); |
|
183 |
|
184 printf("Test 1 - GetService():\n"); |
|
185 if (NS_FAILED(res) || !t) { |
|
186 printf("\t1st GetService failed\n"); |
|
187 ok = false; |
|
188 } |
|
189 |
|
190 NS_IF_RELEASE(t); |
|
191 |
|
192 res = CallGetService(kLBrkCID, &t); |
|
193 |
|
194 if (NS_FAILED(res) || !t) { |
|
195 printf("\t2nd GetService failed\n"); |
|
196 ok = false; |
|
197 } else { |
|
198 printf("Test 4 - {First,Next}ForwardBreak():\n"); |
|
199 if( TestASCIILB(t, teng1, sizeof(teng1)/sizeof(char), |
|
200 exp1, sizeof(exp1)/sizeof(uint32_t)) ) |
|
201 { |
|
202 printf("Test 4 Passed\n\n"); |
|
203 } else { |
|
204 ok = false; |
|
205 printf("Test 4 Failed\n\n"); |
|
206 } |
|
207 |
|
208 printf("Test 5 - {First,Next}ForwardBreak():\n"); |
|
209 if(TestASCIILB(t, teng2, sizeof(teng2)/sizeof(char), |
|
210 lexp2, sizeof(lexp2)/sizeof(uint32_t)) ) |
|
211 { |
|
212 printf("Test 5 Passed\n\n"); |
|
213 } else { |
|
214 ok = false; |
|
215 printf("Test 5 Failed\n\n"); |
|
216 } |
|
217 |
|
218 printf("Test 6 - {First,Next}ForwardBreak():\n"); |
|
219 if(TestASCIILB(t, teng3, sizeof(teng3)/sizeof(char), |
|
220 exp3, sizeof(exp3)/sizeof(uint32_t)) ) |
|
221 { |
|
222 printf("Test 6 Passed\n\n"); |
|
223 } else { |
|
224 ok = false; |
|
225 printf("Test 6 Failed\n\n"); |
|
226 } |
|
227 |
|
228 |
|
229 NS_RELEASE(t); |
|
230 |
|
231 } |
|
232 |
|
233 printf("===========================\n"); |
|
234 printf("Finish nsILineBreaker Test \n"); |
|
235 printf("===========================\n"); |
|
236 |
|
237 return ok; |
|
238 } |
|
239 |
|
240 bool TestWordBreaker() |
|
241 { |
|
242 printf("===========================\n"); |
|
243 printf("Finish nsIWordBreaker Test \n"); |
|
244 printf("===========================\n"); |
|
245 nsIWordBreaker *t = nullptr; |
|
246 nsresult res; |
|
247 bool ok = true; |
|
248 res = CallGetService(kWBrkCID, &t); |
|
249 |
|
250 printf("Test 1 - GetService():\n"); |
|
251 if (NS_FAILED(res) || !t) { |
|
252 printf("\t1st GetService failed\n"); |
|
253 ok = false; |
|
254 } else { |
|
255 NS_RELEASE(t); |
|
256 } |
|
257 |
|
258 res = CallGetService(kWBrkCID, &t); |
|
259 |
|
260 if (NS_FAILED(res) || !t) { |
|
261 printf("\t2nd GetService failed\n"); |
|
262 ok = false; |
|
263 } else { |
|
264 |
|
265 printf("Test 4 - {First,Next}ForwardBreak():\n"); |
|
266 if( TestASCIIWB(t, teng1, sizeof(teng1)/sizeof(char), |
|
267 wexp1, sizeof(wexp1)/sizeof(uint32_t)) ) |
|
268 { |
|
269 printf("Test 4 Passed\n\n"); |
|
270 } else { |
|
271 ok = false; |
|
272 printf("Test 4 Failed\n\n"); |
|
273 } |
|
274 |
|
275 printf("Test 5 - {First,Next}ForwardBreak():\n"); |
|
276 if(TestASCIIWB(t, teng2, sizeof(teng2)/sizeof(char), |
|
277 wexp2, sizeof(wexp2)/sizeof(uint32_t)) ) |
|
278 { |
|
279 printf("Test 5 Passed\n\n"); |
|
280 } else { |
|
281 ok = false; |
|
282 printf("Test 5 Failed\n\n"); |
|
283 } |
|
284 |
|
285 printf("Test 6 - {First,Next}ForwardBreak():\n"); |
|
286 if(TestASCIIWB(t, teng3, sizeof(teng3)/sizeof(char), |
|
287 wexp3, sizeof(wexp3)/sizeof(uint32_t)) ) |
|
288 { |
|
289 printf("Test 6 Passed\n\n"); |
|
290 } else { |
|
291 ok = false; |
|
292 printf("Test 6 Failed\n\n"); |
|
293 } |
|
294 |
|
295 |
|
296 NS_RELEASE(t); |
|
297 } |
|
298 |
|
299 printf("===========================\n"); |
|
300 printf("Finish nsIWordBreaker Test \n"); |
|
301 printf("===========================\n"); |
|
302 |
|
303 return ok; |
|
304 } |
|
305 |
|
306 void SamplePrintWordWithBreak(); |
|
307 void SampleFindWordBreakFromPosition(uint32_t fragN, uint32_t offset); |
|
308 // Sample Code |
|
309 |
|
310 // 012345678901234 |
|
311 static const char wb0[] = "T"; |
|
312 static const char wb1[] = "h"; |
|
313 static const char wb2[] = "is is a int"; |
|
314 static const char wb3[] = "ernationali"; |
|
315 static const char wb4[] = "zation work."; |
|
316 |
|
317 static const char* wb[] = {wb0,wb1,wb2,wb3,wb4}; |
|
318 void SampleWordBreakUsage() |
|
319 { |
|
320 SamplePrintWordWithBreak(); |
|
321 SampleFindWordBreakFromPosition(0,0); // This |
|
322 SampleFindWordBreakFromPosition(1,0); // This |
|
323 SampleFindWordBreakFromPosition(2,0); // This |
|
324 SampleFindWordBreakFromPosition(2,1); // This |
|
325 SampleFindWordBreakFromPosition(2,9); // [space] |
|
326 SampleFindWordBreakFromPosition(2,10); // internationalization |
|
327 SampleFindWordBreakFromPosition(3,4); // internationalization |
|
328 SampleFindWordBreakFromPosition(3,8); // internationalization |
|
329 SampleFindWordBreakFromPosition(4,6); // [space] |
|
330 SampleFindWordBreakFromPosition(4,7); // work |
|
331 } |
|
332 |
|
333 |
|
334 void SamplePrintWordWithBreak() |
|
335 { |
|
336 uint32_t numOfFragment = sizeof(wb) / sizeof(char*); |
|
337 nsIWordBreaker *wbk = nullptr; |
|
338 |
|
339 CallGetService(kWBrkCID, &wbk); |
|
340 |
|
341 nsAutoString result; |
|
342 |
|
343 for(uint32_t i = 0; i < numOfFragment; i++) |
|
344 { |
|
345 NS_ConvertASCIItoUTF16 fragText(wb[i]); |
|
346 |
|
347 int32_t cur = 0; |
|
348 cur = wbk->NextWord(fragText.get(), fragText.Length(), cur); |
|
349 uint32_t start = 0; |
|
350 for(uint32_t j = 0; cur != NS_WORDBREAKER_NEED_MORE_TEXT ; j++) |
|
351 { |
|
352 result.Append(Substring(fragText, start, cur - start)); |
|
353 result.Append('^'); |
|
354 start = (cur >= 0 ? cur : cur - start); |
|
355 cur = wbk->NextWord(fragText.get(), fragText.Length(), cur); |
|
356 } |
|
357 |
|
358 result.Append(Substring(fragText, fragText.Length() - start)); |
|
359 |
|
360 if( i != (numOfFragment -1 )) |
|
361 { |
|
362 NS_ConvertASCIItoUTF16 nextFragText(wb[i+1]); |
|
363 |
|
364 bool canBreak = true; |
|
365 canBreak = wbk->BreakInBetween( fragText.get(), |
|
366 fragText.Length(), |
|
367 nextFragText.get(), |
|
368 nextFragText.Length()); |
|
369 if(canBreak) |
|
370 result.Append('^'); |
|
371 |
|
372 fragText.Assign(nextFragText); |
|
373 } |
|
374 } |
|
375 printf("Output From SamplePrintWordWithBreak() \n\n"); |
|
376 printf("[%s]\n", NS_ConvertUTF16toUTF8(result).get()); |
|
377 |
|
378 NS_IF_RELEASE(wbk); |
|
379 } |
|
380 |
|
381 void SampleFindWordBreakFromPosition(uint32_t fragN, uint32_t offset) |
|
382 { |
|
383 uint32_t numOfFragment = sizeof(wb) / sizeof(char*); |
|
384 nsIWordBreaker *wbk = nullptr; |
|
385 |
|
386 CallGetService(kWBrkCID, &wbk); |
|
387 |
|
388 NS_ConvertASCIItoUTF16 fragText(wb[fragN]); |
|
389 |
|
390 nsWordRange res = wbk->FindWord(fragText.get(), fragText.Length(), offset); |
|
391 |
|
392 bool canBreak; |
|
393 nsAutoString result(Substring(fragText, res.mBegin, res.mEnd-res.mBegin)); |
|
394 |
|
395 if((uint32_t)fragText.Length() == res.mEnd) // if we hit the end of the fragment |
|
396 { |
|
397 nsAutoString curFragText = fragText; |
|
398 for(uint32_t p = fragN +1; p < numOfFragment ;p++) |
|
399 { |
|
400 NS_ConvertASCIItoUTF16 nextFragText(wb[p]); |
|
401 canBreak = wbk->BreakInBetween(curFragText.get(), |
|
402 curFragText.Length(), |
|
403 nextFragText.get(), |
|
404 nextFragText.Length()); |
|
405 if(canBreak) |
|
406 break; |
|
407 |
|
408 nsWordRange r = wbk->FindWord(nextFragText.get(), nextFragText.Length(), |
|
409 0); |
|
410 |
|
411 result.Append(Substring(nextFragText, r.mBegin, r.mEnd - r.mBegin)); |
|
412 |
|
413 if((uint32_t)nextFragText.Length() != r.mEnd) |
|
414 break; |
|
415 |
|
416 nextFragText.Assign(curFragText); |
|
417 } |
|
418 } |
|
419 |
|
420 if(0 == res.mBegin) // if we hit the beginning of the fragment |
|
421 { |
|
422 nsAutoString curFragText = fragText; |
|
423 for(uint32_t p = fragN ; p > 0 ;p--) |
|
424 { |
|
425 NS_ConvertASCIItoUTF16 prevFragText(wb[p-1]); |
|
426 canBreak = wbk->BreakInBetween(prevFragText.get(), |
|
427 prevFragText.Length(), |
|
428 curFragText.get(), |
|
429 curFragText.Length()); |
|
430 if(canBreak) |
|
431 break; |
|
432 |
|
433 nsWordRange r = wbk->FindWord(prevFragText.get(), prevFragText.Length(), |
|
434 prevFragText.Length()); |
|
435 |
|
436 result.Insert(Substring(prevFragText, r.mBegin, r.mEnd - r.mBegin), 0); |
|
437 |
|
438 if(0 != r.mBegin) |
|
439 break; |
|
440 |
|
441 prevFragText.Assign(curFragText); |
|
442 } |
|
443 } |
|
444 |
|
445 printf("Output From SamplePrintWordWithBreak() \n\n"); |
|
446 printf("[%s]\n", NS_ConvertUTF16toUTF8(result).get()); |
|
447 |
|
448 NS_IF_RELEASE(wbk); |
|
449 } |
|
450 |
|
451 // Main |
|
452 |
|
453 int main(int argc, char** argv) { |
|
454 |
|
455 int rv = 0; |
|
456 ScopedXPCOM xpcom("TestLineBreak"); |
|
457 if (xpcom.failed()) |
|
458 return -1; |
|
459 |
|
460 // -------------------------------------------- |
|
461 printf("Test Line Break\n"); |
|
462 |
|
463 bool lbok ; |
|
464 bool wbok ; |
|
465 lbok =TestWordBreaker(); |
|
466 if(lbok) |
|
467 passed("Line Break Test"); |
|
468 else { |
|
469 fail("Line Break Test"); |
|
470 rv = -1; |
|
471 } |
|
472 |
|
473 wbok = TestLineBreaker(); |
|
474 if(wbok) |
|
475 passed("Word Break Test"); |
|
476 else { |
|
477 fail("Word Break Test"); |
|
478 rv = -1; |
|
479 } |
|
480 |
|
481 SampleWordBreakUsage(); |
|
482 |
|
483 |
|
484 // -------------------------------------------- |
|
485 printf("Finish All The Test Cases\n"); |
|
486 |
|
487 if(lbok && wbok) |
|
488 passed("Line/Word Break Test"); |
|
489 else { |
|
490 fail("Line/Word Break Test"); |
|
491 rv = -1; |
|
492 } |
|
493 return rv; |
|
494 } |