[AT-SPI] Catch exception by reference
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-BidirectionalSupport.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
18 #include <iostream>
19 #include <stdlib.h>
20
21 #include <dali/devel-api/text-abstraction/bidirectional-support.h>
22 #include <dali-toolkit/internal/text/bidirectional-support.h>
23 #include <dali-toolkit/internal/text/character-set-conversion.h>
24 #include <dali-toolkit/internal/text/text-run-container.h>
25 #include <dali-toolkit-test-suite-utils.h>
26 #include <dali-toolkit/dali-toolkit.h>
27 #include <toolkit-text-utils.h>
28
29 using namespace Dali;
30 using namespace Toolkit;
31 using namespace Text;
32
33 // Tests the following functions.
34 //
35 // void SetBidirectionalInfo( const Vector<Character>& text,
36 //                            const Vector<ScriptRun>& scripts,
37 //                            const Vector<LineBreakInfo>& lineBreakInfo,
38 //                            CharacterIndex startIndex,
39 //                            Length numberOfCharacters,
40 //                            Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo )
41 // bool GetMirroredText( const Vector<Character>& text,
42 //                       Vector<CharacterDirection>& directions,
43 //                       const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
44 //                       CharacterIndex startIndex,
45 //                       Length numberOfCharacters,
46 //                       Vector<Character>& mirroredText )
47 // void GetCharactersDirection( const Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
48 //                              Length totalNumberOfCharacters,
49 //                              CharacterIndex startIndex,
50 //                              Length numberOfCharacters,
51 //                              Vector<CharacterDirection>& directions )
52
53 //////////////////////////////////////////////////////////
54
55 namespace
56 {
57
58 struct SetBidirectionalInfoData
59 {
60   std::string   description;                 ///< Description of the test.
61   std::string   text;                        ///< Input text.
62   unsigned int  startIndex;                  ///< The index from where the model is updated.
63   unsigned int  numberOfCharacters;          ///< The number of characters to update.
64   unsigned int  numberOfParagraphs;          ///< The expected number of bidirectional paragraphs.
65   unsigned int* indices;                     ///< The expected indices to the first character of each paragraph.
66   unsigned int* numberOfParagraphCharacters; ///< The expected number of characters of each paragraph.
67   bool*         directions;                  ///< The expected direction of each paragraph.
68 };
69
70 struct BidiLineData
71 {
72   unsigned int  characterIndex;
73   unsigned int  numberOfCharacters;
74   unsigned int* visualToLogical;
75 };
76
77 struct GetMirroredTextData
78 {
79   std::string  description;        ///< Description of the test.
80   std::string  text;               ///< Input text.
81   unsigned int startIndex;         ///< The index from where the model is updated.
82   unsigned int numberOfCharacters; ///< The number of the characters.
83   std::string  mirroredText;       ///< The expected result.
84 };
85
86 struct GetCharactersDirectionData
87 {
88   std::string  description;            ///< Description of the test.
89   std::string  text;                   ///< Input text.
90   unsigned int startIndex;             ///< The index from where the model is updated.
91   unsigned int numberOfCharacters;     ///< The number of characters.
92   bool*        directions;             ///< The expected directions.
93   bool         markupProcessorEnabled; ///< Enable markup processor to use markup text.
94 };
95
96 bool SetBidirectionalInfoTest( const SetBidirectionalInfoData& data )
97 {
98   // 1) Create the model.
99   ModelPtr textModel;
100   MetricsPtr metrics;
101   Size textArea(100.f, 60.f);
102   Size layoutSize;
103
104   // Create the model.
105   const Vector<FontDescriptionRun> fontDescriptions;
106   const LayoutOptions options;
107   CreateTextModel( data.text,
108                    textArea,
109                    fontDescriptions,
110                    options,
111                    layoutSize,
112                    textModel,
113                    metrics,
114                    false );
115
116   LogicalModelPtr logicalModel = textModel->mLogicalModel;
117   VisualModelPtr visualModel = textModel->mVisualModel;
118
119   // 2) Clear the bidirectional paragraph info data.
120   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
121   if( 0u != data.numberOfCharacters )
122   {
123     ClearCharacterRuns( data.startIndex,
124                         data.startIndex + data.numberOfCharacters - 1u,
125                         bidirectionalInfo );
126   }
127
128   // 3) Call the SetBidirectionalInfo() function.
129   SetBidirectionalInfo( logicalModel->mText,
130                         logicalModel->mScriptRuns,
131                         logicalModel->mLineBreakInfo,
132                         data.startIndex,
133                         data.numberOfCharacters,
134                         bidirectionalInfo );
135
136   // 4) Compare with the expected results.
137   TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
138
139   if( data.numberOfParagraphs != bidirectionalInfo.Count() )
140   {
141     // Different number of expected bidirectional paragraphs.
142     std::cout << "  Different number of bidi paragraphs : " << bidirectionalInfo.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
143     return false;
144   }
145
146   for( unsigned int index = 0u; index < data.numberOfParagraphs; ++index )
147   {
148     const BidirectionalParagraphInfoRun& run = bidirectionalInfo[index];
149
150     const CharacterDirection direction = bidirectionalSupport.GetParagraphDirection( run.bidirectionalInfoIndex );
151     if( direction != data.directions[index] )
152     {
153       std::cout << "  Different direction" << std::endl;
154       std::cout << "        paragraph : " << index << std::endl;
155       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
156       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
157       return false;
158     }
159
160     if( run.characterRun.characterIndex != data.indices[index] )
161     {
162       std::cout << "  Different index" << std::endl;
163       std::cout << "        paragraph : " << index << std::endl;
164       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
165       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
166       return false;
167     }
168     if( run.characterRun.numberOfCharacters != data.numberOfParagraphCharacters[index] )
169     {
170       std::cout << "  Different number of characters" << std::endl;
171       std::cout << "        paragraph : " << index << std::endl;
172       std::cout << "            index : " << run.characterRun.characterIndex << ", num chars : " << run.characterRun.numberOfCharacters << ", direction : " << direction << std::endl;
173       std::cout << "  expected, index : " << data.indices[index] << ", num chars : " << data.numberOfParagraphCharacters[index] << ", direction : " << data.directions[index] << std::endl;
174       return false;
175     }
176   }
177
178   return true;
179 }
180
181 bool GetMirroredTextTest( const GetMirroredTextData& data )
182 {
183   // 1) Create the model.
184   ModelPtr textModel;
185   MetricsPtr metrics;
186   Size textArea(100.f, 60.f);
187   Size layoutSize;
188
189   // Create the model.
190   const Vector<FontDescriptionRun> fontDescriptions;
191   const LayoutOptions options;
192   CreateTextModel( data.text,
193                    textArea,
194                    fontDescriptions,
195                    options,
196                    layoutSize,
197                    textModel,
198                    metrics,
199                    false );
200
201   LogicalModelPtr logicalModel = textModel->mLogicalModel;
202   VisualModelPtr visualModel = textModel->mVisualModel;
203
204   // 2) Call the GetMirroredText() function for the whole text
205   Vector<Character> mirroredText;
206   bool mirrored = false;
207   mirrored = GetMirroredText( logicalModel->mText,
208                               logicalModel->mCharacterDirections,
209                               logicalModel->mBidirectionalParagraphInfo,
210                               0u,
211                               logicalModel->mText.Count(),
212                               mirroredText );
213
214   // 3) Call the GetMirroredText() function for the given index + number of characters
215   mirrored = GetMirroredText( logicalModel->mText,
216                               logicalModel->mCharacterDirections,
217                               logicalModel->mBidirectionalParagraphInfo,
218                               data.startIndex,
219                               data.numberOfCharacters,
220                               mirroredText );
221
222   // 4) Compare the results.
223
224   // Convert to utf8
225   std::string mirroredString;
226   Utf32ToUtf8( mirroredText.Begin(),
227                mirroredText.Count(),
228                mirroredString );
229
230   if( !mirrored && ( mirroredString != data.text ) )
231   {
232     std::cout << "  No mirrored text and mirroredString != data.text." << std::endl;
233     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
234     std::cout << "             text : [" << data.text << "]" << std::endl;
235     return false;
236   }
237
238   if( mirrored && ( mirroredString == data.text ) )
239   {
240     std::cout << "  Mirrored text and mirroredString == data.text." << std::endl;
241     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
242     std::cout << "             text : [" << data.text << "]" << std::endl;
243     return false;
244   }
245
246   if( mirrored && ( mirroredString != data.mirroredText ) )
247   {
248     std::cout << "  Mirrored text and mirroredString != data.mirroredText." << std::endl;
249     std::cout << "  mirrored string : [" << mirroredString << "]" << std::endl;
250     std::cout << "             text : [" << data.mirroredText << "]" << std::endl;
251     return false;
252   }
253
254   return true;
255 }
256
257 bool GetCharactersDirectionTest( const GetCharactersDirectionData& data )
258 {
259   // 1) Create the model.
260   ModelPtr textModel;
261   MetricsPtr metrics;
262   Size textArea(100.f, 60.f);
263   Size layoutSize;
264
265   // Create the model.
266   const Vector<FontDescriptionRun> fontDescriptions;
267   const LayoutOptions options;
268   CreateTextModel( data.text,
269                    textArea,
270                    fontDescriptions,
271                    options,
272                    layoutSize,
273                    textModel,
274                    metrics,
275                    data.markupProcessorEnabled );
276
277   LogicalModelPtr logicalModel = textModel->mLogicalModel;
278   VisualModelPtr visualModel = textModel->mVisualModel;
279
280   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
281
282   // 2) Clear the direction info data.
283   Vector<CharacterDirection>& directions = logicalModel->mCharacterDirections;
284
285   if( directions.Count() >= data.startIndex + data.numberOfCharacters )
286   {
287     directions.Erase( directions.Begin() + data.startIndex,
288                       directions.Begin() + data.startIndex + data.numberOfCharacters );
289   }
290
291   // 3) Call GetCharactersDirection() function.
292
293   GetCharactersDirection( bidirectionalInfo,
294                           logicalModel->mText.Count(),
295                           data.startIndex,
296                           data.numberOfCharacters,
297                           directions );
298
299   for( unsigned int index = 0u; index < logicalModel->mText.Count(); ++index )
300   {
301     if( data.directions[index] != directions[index] )
302     {
303       return false;
304     }
305   }
306
307   return true;
308 }
309
310 } // namespace
311
312 //////////////////////////////////////////////////////////
313
314 int UtcDaliSetBidirectionalInfo(void)
315 {
316   tet_infoline(" UtcDaliSetBidirectionalInfo");
317
318   unsigned int indices01[] = {};
319   unsigned int numberOfCharacters01[] = {};
320   bool         direction01[] = {};
321   unsigned int indices02[] = {};
322   unsigned int numberOfCharacters02[] = {};
323   bool         direction02[] = {};
324   unsigned int indices03[] = { 17u, 48u };
325   unsigned int numberOfCharacters03[] = { 14u, 14u };
326   bool         direction03[] = { true, true };
327   unsigned int indices04[] = { 17u, 31u, 79u };
328   unsigned int numberOfCharacters04[] = { 14u, 48u, 31u };
329   bool         direction04[] = { true, false, true };
330   unsigned int indices05[] = { 17u, 41u, 117u };
331   unsigned int numberOfCharacters05[] = { 24u, 76u, 49u };
332   bool         direction05[] = { true, false, true };
333   unsigned int indices06[] = { 17u, 48u };
334   unsigned int numberOfCharacters06[] = { 14u, 14u };
335   bool         direction06[] = { true, true };
336   unsigned int indices07[] = { 17u, 31u, 79u };
337   unsigned int numberOfCharacters07[] = { 14u, 48u, 31u };
338   bool         direction07[] = { true, false, true };
339   unsigned int indices08[] = { 17u, 41u, 117u };
340   unsigned int numberOfCharacters08[] = { 24u, 76u, 49u };
341   bool         direction08[] = { true, false, true };
342
343   struct SetBidirectionalInfoData data[] =
344   {
345     {
346       "Zero characters",
347       "",
348       0u,
349       0u,
350       0u,
351       indices01,
352       numberOfCharacters01,
353       direction01
354     },
355     {
356       "Some left to right paragraphs",
357       "Hello world\ndemo\n\n",
358       0u,
359       18u,
360       0u,
361       indices02,
362       numberOfCharacters02,
363       direction02
364     },
365     {
366       "A mix of left to right and right to left paragraphs.",
367       "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
368       0u,
369       78u,
370       2u,
371       indices03,
372       numberOfCharacters03,
373       direction03
374     },
375     {
376       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
377       "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
378       0u,
379       126u,
380       3u,
381       indices04,
382       numberOfCharacters04,
383       direction04
384     },
385     {
386       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts.",
387       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
388       0u,
389       182u,
390       3u,
391       indices05,
392       numberOfCharacters05,
393       direction05
394     },
395     {
396       "A mix of left to right and right to left paragraphs. Updates a left to right paragraph.",
397       "Hello world demo\nمرحبا بالعالم\nhello world demo\nمرحبا بالعالم\nhello world demo",
398       31u,
399       17u,
400       2u,
401       indices06,
402       numberOfCharacters06,
403       direction06
404     },
405     {
406       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text.",
407       "Hello world demo\nمرحبا بالعالم\nhello world demo مرحبا بالعالم hello world demo\nمرحبا hello world demo بالعالم\nhello world demo",
408       0u,
409       126u,
410       3u,
411       indices07,
412       numberOfCharacters07,
413       direction07
414     },
415     {
416       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates initial paragraphs.",
417       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
418       0u,
419       41u,
420       3u,
421       indices08,
422       numberOfCharacters08,
423       direction08
424     },
425     {
426       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates mid paragraphs.",
427       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
428       41u,
429       76u,
430       3u,
431       indices08,
432       numberOfCharacters08,
433       direction08
434     },
435     {
436       "A mix of left to right and right to left paragraphs. Paragraphs also contain a mix of bidirectional text and a mix of right to left scripts. Updates from character 85",
437       "Hello world demo\nمرحبا שלום עולם بالعالم\nhello world שלום بالعالم עולם demo مرحبا שלום עולם بالعالم hello world demo\nمرحبا hello שלום بالعالم עולם world demo بالعالم\nhello world demo",
438       117u,
439       65u,
440       3u,
441       indices08,
442       numberOfCharacters08,
443       direction08
444     },
445   };
446   const unsigned int numberOfTests = 10u;
447
448   for( unsigned int index = 0u; index < numberOfTests; ++index )
449   {
450     ToolkitTestApplication application;
451     if( !SetBidirectionalInfoTest( data[index] ) )
452     {
453       tet_result(TET_FAIL);
454     }
455   }
456
457   tet_result(TET_PASS);
458   END_TEST;
459 }
460
461 int UtcDaliGetMirroredText(void)
462 {
463   tet_infoline(" UtcDaliGetMirroredText");
464
465   struct GetMirroredTextData data[] =
466   {
467     {
468       "Zero characters.",
469       "",
470       0u,
471       0u,
472       ""
473     },
474     {
475       "Left to right characters only.",
476       "Hello world\nhello world demo.",
477       0u,
478       29u,
479       "Hello world\nhello world demo."
480     },
481     {
482       "Right to left characters but with no characters to mirror.",
483       "שלום עולם\nمرحبا بالعالم",
484       0u,
485       23u,
486       "שלום עולם\nمرحبا بالعالم"
487     },
488     {
489       "Right to left characters with some characters to mirror.",
490       "שלום עולם\n(مرحبا بالعالم)",
491       0u,
492       25u,
493       "שלום עולם\n)مرحبا بالعالم("
494     },
495     {
496       "Right to left characters with some characters to mirror. Update last paragraph.",
497       "שלום עולם\n(مرحبا بالعالم)",
498       10u,
499       15u,
500       "שלום עולם\n)مرحبا بالعالم("
501     },
502     {
503       "Mix of bidirectional text. With more paragraphs.",
504       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
505       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
506       0u,
507       239u,
508       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
509       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום )hello) world demo )עולם(\nשלום )مرحبا بالعالم עולם( )hello("
510     },
511     {
512       "Mix of bidirectional text. With more paragraphs. Update middle paragraphs.",
513       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
514       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
515       29u,
516       38u,
517       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום( עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
518       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"
519     },
520     {
521       "Mix of bidirectional text. With more paragraphs. Update middle paragraphs (2).",
522       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם (hello) مرحبا بالعالم world"
523       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)",
524       67u,
525       100u,
526       "Hello world demo\nhello world\nhello world (مرحبا بالعالم שלום) עולם\nשלום مرحبا بالعالم עולם )hello( مرحبا بالعالم world"
527       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום (hello) world demo (עולם)\nשלום (مرحبا بالعالم עולם) (hello)"
528     },
529   };
530   const unsigned int numberOfTests = 8u;
531
532   for( unsigned int index = 0u; index < numberOfTests; ++index )
533   {
534     ToolkitTestApplication application;
535     if( !GetMirroredTextTest( data[index] ) )
536     {
537       tet_result(TET_FAIL);
538     }
539   }
540
541   tet_result(TET_PASS);
542   END_TEST;
543 }
544
545 int UtcDaliGetCharactersDirection(void)
546 {
547   tet_infoline(" UtcDaliGetCharactersDirection");
548
549   bool directions01[] = {};
550   bool directions02[] = {
551     false, false, false, false, false, false, false, false, false, false,
552     false, false, false, false, false, false, false, false, false, false,
553     false, false, false, false, false, false, false, false };
554   bool directions03[] = {
555     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
556     true,  true,  true,  true,  true,  true,  true,  true,  true };
557   bool directions04[] = {
558     false, false, false, false, false, false, false, false, false, false,
559     false, false, false, false, false, false, false, false, false, false,
560     false, false, false, false, true,  true,  true,  true,  true,  true,
561     true,  true,  true,  false, true,  true,  true,  true,  true,  true,
562     true,  true,  true,  true,  false, false, false, false, false, false,
563     false, false, false, false, false };
564   bool directions05[] = {
565     false, false, false, false, false, false, false, false, false, false,
566     false, false, false, false, false, false, false, false, false, false,
567     false, false, false, false, false, false, false, false, false, false,
568     false, false, false, false, false, false, false, false, false, false,
569     false, true,  true,  true,  true,  true,  true,  true,  true,  true,
570     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
571     true,  true,  true,  true,  false, true,  true,  true,  true,  true,
572     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
573     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
574     false, false, false, false, true,  true,  true,  true,  true,  true,
575     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
576     false, false, false, false, true,  true,  true,  true,  true,  true,
577     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
578     true,  true,  true,  true,  true,  true,  true,  true,  true,  false,
579     false, false, false, false, false, false, false, false, false, false,
580     false, false, false, false, false, false, false, false, false, false,
581     false, false, true,  true,  true,  true,  true,  true,  true,  true,
582     true,  true,  true,  true,  true,  true,  false, false, false, false,
583     false, false, false, false, false, false, false, false, false, false,
584     false, false, true,  true,  true,  true,  true,  true,  true,  true,
585     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
586     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
587     true,  true,  false, false, false, false, false };
588
589     bool directions06[] = {
590     true,  true,  true,  true,  true,  true,  true,  true,  true, true,
591     false, false, false, false, false, false, false, false, false, false,
592     false, false, false, false, false, false };
593
594   struct GetCharactersDirectionData data[] =
595   {
596     {
597       "Zero characters",
598       "",
599       0u,
600       0u,
601       directions01,
602       false
603     },
604     {
605       "Left to right characters only",
606       "Hello world\nhello world demo",
607       0u,
608       28u,
609       directions02,
610       false
611     },
612     {
613       "Right to left characters only",
614       "שלום עולם\nשלום עולם",
615       0u,
616       19u,
617       directions03,
618       false
619     },
620     {
621       "Mix of bidirectional text",
622       "Hello world\nhello world שלום עולם\nשלום עולם hello world",
623       0u,
624       55u,
625       directions04,
626       false
627     },
628     {
629       "Mix of bidirectional text. With more paragraphs.",
630       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
631       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
632       0u,
633       227u,
634       directions05,
635       false
636     },
637     {
638       "Mix of bidirectional text. With more paragraphs. Update first paragraph.",
639       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
640       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
641       0u,
642       17u,
643       directions05,
644       false
645     },
646     {
647       "Mix of bidirectional text. With more paragraphs. Update from character 29",
648       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
649       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
650       29u,
651       134u,
652       directions05,
653       false
654     },
655     {
656       "Mix of bidirectional text. With more paragraphs. Update from character 163",
657       "Hello world demo\nhello world\nhello world مرحبا بالعالم שלום עולם\nשלום مرحبا بالعالم עולם hello مرحبا بالعالم world"
658       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
659       163u,
660       35u,
661       directions05,
662       false
663     },
664     {
665       "Mix of bidirectional text. With brackets and LRM",
666       "שלום עולם &lrm;(hello)[world]&lrm;",
667       0u,
668       26u,
669       directions06,
670       true
671     }
672   };
673   const unsigned int numberOfTests = 9u;
674
675   for( unsigned int index = 0u; index < numberOfTests; ++index )
676   {
677     ToolkitTestApplication application;
678     if( !GetCharactersDirectionTest( data[index] ) )
679     {
680       tet_result(TET_FAIL);
681     }
682   }
683
684   tet_result(TET_PASS);
685   END_TEST;
686 }