Multi-line text. Cursor hit and cursor's position.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-LogicalModel.cpp
1 /*
2  * Copyright (c) 2016 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
20 #include <stdlib.h>
21
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/internal/text/text-run-container.h>
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <toolkit-text-model.h>
26
27
28 using namespace Dali;
29 using namespace Toolkit;
30 using namespace Text;
31
32 // Tests the following functions.
33 //
34 // void CreateParagraphInfo( CharacterIndex startIndex,
35 //                           Length numberOfCharacters );
36 // void FindParagraphs( CharacterIndex index,
37 //                      Length numberOfCharacters,
38 //                      Vector<ParagraphRunIndex>& paragraphs );
39 // bool FetchBidirectionalLineInfo( CharacterIndex characterIndex )
40 // CharacterIndex GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const;
41 // CharacterIndex GetLogicalCursorIndex( CharacterIndex visualCursorIndex ) const;
42
43 //////////////////////////////////////////////////////////
44
45 namespace
46 {
47 struct CreateParagraphData
48 {
49   std::string    description;                    ///< Description of the test.
50   std::string    text;                           ///< Input text.
51   CharacterIndex index;                          ///< The first character index.
52   Length         numberOfCharacters;             ///< The number of characters.
53   unsigned int   numberOfParagraphs;             ///< The expected number of paragraphs.
54   unsigned int*  indices;                        ///< The expected paragraph info indices.
55   unsigned int*  numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
56 };
57
58 struct FindParagraphData
59 {
60   std::string    description;        ///< Description of the test.
61   std::string    text;               ///< Input text.
62   CharacterIndex index;              ///< The first character index.
63   Length         numberOfCharacters; ///< The number of characters.
64   unsigned int   numberOfParagraphs; ///< The expected number of paragraphs.
65   unsigned int*  paragraphs;         ///< The expected paragraph info.
66 };
67
68 struct FetchBidirectionalLineInfoData
69 {
70   std::string   description;    ///< Description of the test.
71   std::string   text;           ///< Input text.
72   unsigned int  numberOfTests;  ///< The number of tests.
73   unsigned int* characterIndex; ///< The logical character index.
74   bool*         fetched;        ///< Whether the expected bidi line exists.
75   unsigned int* bidiLineIndex;  ///< Index to the expected bidi line.
76 };
77
78 struct GetLogicalCharacterIndexData
79 {
80   std::string   description;        ///< Description of the test.
81   std::string   text;               ///< Input text.
82   Size          textArea;           ///< The text area.
83   unsigned int  numberOfIndices;    ///< The number of characters to set.
84   unsigned int* visualToLogical;    ///< The expected visual to logical conversion table.
85   unsigned int* cachedBidiLine;     ///< The cached bidi line index for each character.
86 };
87
88 struct GetLogicalCursorIndexData
89 {
90   std::string    description;        ///< Description of the test.
91   std::string    text;               ///< Input text.
92   Size           textArea;           ///< The text area.
93   unsigned int   numberOfIndices;    ///< The number of characters to set.
94   unsigned int*  visualCursorIndex;  ///< The given cursor visual index.
95   unsigned int*  characterIndex;     ///< Index to the first logical character of the line.
96   unsigned int*  logicalCursorIndex; ///< The expected cursor logical index.
97   unsigned int*  cachedBidiLine;     ///< The cached bidi line index for each character.
98 };
99
100 bool CreateParagraphTest( const CreateParagraphData& data )
101 {
102   // 1) Create the model.
103   LogicalModelPtr logicalModel;
104   VisualModelPtr visualModel;
105   MetricsPtr metrics;
106   Size textArea(100.f, 60.f);
107   Size layoutSize;
108
109   Vector<FontDescriptionRun> fontDescriptionRuns;
110   LayoutOptions options;
111   CreateTextModel( data.text,
112                    textArea,
113                    fontDescriptionRuns,
114                    options,
115                    layoutSize,
116                    logicalModel,
117                    visualModel,
118                    metrics );
119
120   // 2) Clear the paragraphs.
121   Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
122   ClearCharacterRuns( data.index,
123                       data.index + data.numberOfCharacters - 1u,
124                       paragraphs );
125
126   // 3) Call the LogicalModel::CreateParagraphInfo() method
127   logicalModel->CreateParagraphInfo( data.index,
128                                      data.numberOfCharacters );
129
130   // 4) Compare the results.
131   if( data.numberOfParagraphs != paragraphs.Count() )
132   {
133     std::cout << "  Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
134     return false;
135   }
136
137   unsigned int index = 0u;
138   for( Vector<ParagraphRun>::ConstIterator it = paragraphs.Begin(),
139          endIt = paragraphs.End();
140        it != endIt;
141        ++it, ++index )
142   {
143     const ParagraphRun& paragraph( *it );
144
145     if( data.indices[index] != paragraph.characterRun.characterIndex )
146     {
147       std::cout << "  Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
148       return false;
149     }
150     if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
151     {
152       std::cout << "  Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
153       return false;
154     }
155   }
156
157   return true;
158 }
159
160 bool FindParagraphTest( const FindParagraphData& data )
161 {
162   // 1) Create the model.
163   LogicalModelPtr logicalModel;
164   VisualModelPtr visualModel;
165   MetricsPtr metrics;
166   Size textArea(100.f, 60.f);
167   Size layoutSize;
168
169   Vector<FontDescriptionRun> fontDescriptionRuns;
170   LayoutOptions options;
171   CreateTextModel( data.text,
172                    textArea,
173                    fontDescriptionRuns,
174                    options,
175                    layoutSize,
176                    logicalModel,
177                    visualModel,
178                    metrics );
179
180   // 2) Find the paragraphs.
181   Vector<ParagraphRunIndex> paragraphs;
182   logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
183
184   // 3) compare the results.
185   if( data.numberOfParagraphs != paragraphs.Count() )
186   {
187     return false;
188   }
189
190   unsigned int index = 0u;
191   for( Vector<ParagraphRunIndex>::ConstIterator it = paragraphs.Begin(),
192          endIt = paragraphs.End();
193        it != endIt;
194        ++it, ++index )
195   {
196     const ParagraphRunIndex paragraphIndex = *it;
197
198     if( paragraphIndex != data.paragraphs[index] )
199     {
200       return false;
201     }
202   }
203
204   return true;
205 }
206
207 bool FetchBidirectionalLineInfoTest( const FetchBidirectionalLineInfoData& data )
208 {
209   std::cout << "  testing : " << data.description << std::endl;
210   // Create the model.
211   LogicalModelPtr logicalModel;
212   VisualModelPtr visualModel;
213   MetricsPtr metrics;
214   Size textArea( 100.f, 300.f );
215   Size layoutSize;
216
217   // Create the model with the whole text.
218   const Vector<FontDescriptionRun> fontDescriptions;
219   const LayoutOptions options;
220   CreateTextModel( data.text,
221                    textArea,
222                    fontDescriptions,
223                    options,
224                    layoutSize,
225                    logicalModel,
226                    visualModel,
227                    metrics );
228
229   for( unsigned int index = 0; index < data.numberOfTests; ++index )
230   {
231     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
232
233     if( fetched != data.fetched[index] )
234     {
235       std::cout << "  Different fetched result : " << fetched << ", expected : " << data.fetched[index] << std::endl;
236       return false;
237     }
238
239     if( fetched )
240     {
241       if( logicalModel->mBidirectionalLineIndex != data.bidiLineIndex[index] )
242       {
243         std::cout << "  Different bidi line index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.bidiLineIndex << std::endl;
244         return false;
245       }
246     }
247   }
248
249   return true;
250 }
251
252 bool GetLogicalCharacterIndexTest( const GetLogicalCharacterIndexData& data )
253 {
254   std::cout << "  testing : " << data.description << std::endl;
255   // Create the model.
256   LogicalModelPtr logicalModel;
257   VisualModelPtr visualModel;
258   MetricsPtr metrics;
259   Size layoutSize;
260
261   // Create the model with the whole text.
262   const Vector<FontDescriptionRun> fontDescriptions;
263   const LayoutOptions options;
264   CreateTextModel( data.text,
265                    data.textArea,
266                    fontDescriptions,
267                    options,
268                    layoutSize,
269                    logicalModel,
270                    visualModel,
271                    metrics );
272
273   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
274   {
275     // Check the current cached bidi line index. (Check it before call the GetLogicalCharacterIndex() method )
276     if( data.cachedBidiLine[index] != logicalModel->mBidirectionalLineIndex )
277     {
278       std::cout << "  index : " << index << ", different cached bidi index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.cachedBidiLine[index] << std::endl;
279       return false;
280     }
281
282     const bool fetched = logicalModel->FetchBidirectionalLineInfo( index );
283     const Character logicalIndex = fetched ? logicalModel->GetLogicalCharacterIndex( index ) : index;
284
285     if( data.visualToLogical[index] != logicalIndex )
286     {
287       std::cout << "  visual index : " << index << ", different logical index : " << logicalIndex << ", expected : " << data.visualToLogical[index] << std::endl;
288       return false;
289     }
290   }
291   return true;
292 }
293
294 bool GetLogicalCursorIndexTest( const GetLogicalCursorIndexData& data )
295 {
296   std::cout << "  testing : " << data.description << std::endl;
297   // Create the model.
298   LogicalModelPtr logicalModel;
299   VisualModelPtr visualModel;
300   MetricsPtr metrics;
301   Size layoutSize;
302
303   // Create the model with the whole text.
304   const Vector<FontDescriptionRun> fontDescriptions;
305   const LayoutOptions options;
306   CreateTextModel( data.text,
307                    data.textArea,
308                    fontDescriptions,
309                    options,
310                    layoutSize,
311                    logicalModel,
312                    visualModel,
313                    metrics );
314
315   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
316   {
317     const bool fetched = logicalModel->FetchBidirectionalLineInfo( data.characterIndex[index] );
318
319     if( logicalModel->mBidirectionalLineIndex != data.cachedBidiLine[index] )
320     {
321       std::cout << "  test : " << index << ", different cached line index : " << logicalModel->mBidirectionalLineIndex << ", expected : " << data.cachedBidiLine[index] << std::endl;
322       return false;
323     }
324
325     const CharacterIndex visualCharacterIndex = data.visualCursorIndex[index];
326     const CharacterIndex logicalCursorIndex = fetched ? logicalModel->GetLogicalCursorIndex( visualCharacterIndex ) : visualCharacterIndex;
327
328     if( logicalCursorIndex != data.logicalCursorIndex[index] )
329     {
330       std::cout << "  test : " << index << ", visual index : " << visualCharacterIndex << ", different logical cursor index : " << logicalCursorIndex << ", expected : " << data.logicalCursorIndex[index] << std::endl;
331       return false;
332     }
333   }
334
335   return true;
336 }
337
338 } // namespace
339
340 //////////////////////////////////////////////////////////
341 //
342 // UtcDaliCreateParagraph
343 // UtcDaliFindParagraph
344 // UtcDaliFetchBidirectionalLineInfo
345 // UtcDaliGetLogicalCharacterIndex
346 // UtcDaliGetLogicalCursorIndex
347 //
348 //////////////////////////////////////////////////////////
349
350 int UtcDaliCreateParagraph(void)
351 {
352   tet_infoline(" UtcDaliCreateParagraph");
353
354   unsigned int paragraphsIndices01[] = { 0u };
355   unsigned int paragraphsNumberOfCharacters01[] = { 0u };
356   unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
357   unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
358   unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
359   unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
360
361   struct CreateParagraphData data[] =
362   {
363     {
364       "Zero characters",
365       "",
366       0u,
367       0u,
368       0u,
369       paragraphsIndices01,
370       paragraphsNumberOfCharacters01,
371     },
372     {
373       "Some paragraphs",
374       "Hello world\ndemo\n\n",
375       0u,
376       18u,
377       3u,
378       paragraphsIndices02,
379       paragraphsNumberOfCharacters02,
380     },
381     {
382       "Some paragraphs. Update the initial paragraphs.",
383       "Hello world\ndemo\nhello world demo\n\n",
384       0u,
385       17u,
386       4u,
387       paragraphsIndices03,
388       paragraphsNumberOfCharacters03,
389     },
390     {
391       "Some paragraphs. Update the mid paragraphs.",
392       "Hello world\ndemo\nhello world demo\n\n",
393       12u,
394       5u,
395       4u,
396       paragraphsIndices03,
397       paragraphsNumberOfCharacters03,
398     },
399     {
400       "Some paragraphs. Update the final paragraphs.",
401       "Hello world\ndemo\nhello world demo\n\n",
402       17u,
403       18u,
404       4u,
405       paragraphsIndices03,
406       paragraphsNumberOfCharacters03,
407     },
408   };
409   const unsigned int numberOfTests = 5u;
410
411   for( unsigned int index = 0u; index < numberOfTests; ++index )
412   {
413     ToolkitTestApplication application;
414     if( !CreateParagraphTest( data[index] ) )
415     {
416       tet_result(TET_FAIL);
417     }
418   }
419
420   tet_result(TET_PASS);
421   END_TEST;
422 }
423
424 int UtcDaliFindParagraph(void)
425 {
426   tet_infoline(" UtcDaliFindParagraph");
427
428   unsigned int paragraphs01[] = {};
429   unsigned int paragraphs02[] = { 0u, 1u, 2u };
430   unsigned int paragraphs03[] = { 0u };
431   unsigned int paragraphs04[] = { 1u };
432   unsigned int paragraphs05[] = { 0u, 1u, 2u };
433
434   struct FindParagraphData data[] =
435   {
436     {
437       "Zero characters",
438       "",
439       0u,
440       100u,
441       0u,
442       paragraphs01,
443     },
444     {
445       "Some paragraphs",
446       "Hello world\ndemo\n\n",
447       0u,
448       18u,
449       3u,
450       paragraphs02
451     },
452     {
453       "Some paragraphs",
454       "Hello world\ndemo\n\n",
455       0u,
456       12u,
457       1u,
458       paragraphs03
459     },
460     {
461       "Some paragraphs",
462       "Hello world\ndemo\n\n",
463       12u,
464       5u,
465       1u,
466       paragraphs04
467     },
468     {
469       "Some paragraphs",
470       "Hello world\ndemo\n\n",
471       3u,
472       15u,
473       3u,
474       paragraphs05
475     },
476   };
477   const unsigned int numberOfTests = 5u;
478
479   for( unsigned int index = 0u; index < numberOfTests; ++index )
480   {
481     ToolkitTestApplication application;
482     if( !FindParagraphTest( data[index] ) )
483     {
484       tet_result(TET_FAIL);
485     }
486   }
487
488   tet_result(TET_PASS);
489   END_TEST;
490 }
491
492 int UtcDaliFetchBidirectionalLineInfo(void)
493 {
494   tet_infoline(" UtcDaliFetchBidirectionalLineInfo");
495
496   unsigned int logicalIndex01[] = { 0u };
497   bool fetched01[] = { false };
498   unsigned int bidiLine01[] = { 0u };
499
500   unsigned int logicalIndex02[] = { 3u };
501   bool fetched02[] = { false };
502   unsigned int bidiLine02[] = { 0u };
503
504   unsigned int logicalIndex03[] = { 0u, 11u, 12u, 21u, 22u, 33u, 34u, 43u, 44u, 54u};
505   bool fetched03[] = { false, false, true, true, false, false, true, true, false, false };
506   unsigned int bidiLine03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 0u, 0u };
507
508   struct FetchBidirectionalLineInfoData data[] =
509   {
510     {
511       "Void text",
512       "",
513       1u,
514       logicalIndex01,
515       fetched01,
516       bidiLine01
517     },
518     {
519       "LTR text",
520       "Hello world",
521       1u,
522       logicalIndex02,
523       fetched02,
524       bidiLine02
525     },
526     {
527       "Bidi text",
528       "Hello world\nשלום עולם\nhello world\nשלום עולם\nhello world",
529       10u,
530       logicalIndex03,
531       fetched03,
532       bidiLine03
533     }
534   };
535   const unsigned int numberOfTests = 3u;
536
537   for( unsigned int index = 0u; index < numberOfTests; ++index )
538   {
539     ToolkitTestApplication application;
540     if( !FetchBidirectionalLineInfoTest( data[index] ) )
541     {
542       tet_result(TET_FAIL);
543     }
544   }
545
546   tet_result(TET_PASS);
547   END_TEST;
548 }
549
550 int UtcDaliGetLogicalCharacterIndex(void)
551 {
552   tet_infoline(" UtcDaliSetVisualToLogicalMap");
553
554   unsigned int visualToLogical01[] = {};
555   unsigned int  cachedBidiLine01[] = {};
556   unsigned int visualToLogical02[] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u };
557   unsigned int  cachedBidiLine02[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,  0u };
558   unsigned int visualToLogical03[] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u };
559   unsigned int  cachedBidiLine03[] = {  0u,  0u,  0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u };
560
561   unsigned int visualToLogical04[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
562   unsigned int  cachedBidiLine04[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
563                                        0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
564                                        1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
565
566 // size 300, 300
567 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
568 //      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
569 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _  h  e  l  l  o  _  w  o  r  l  d \n
570 //      0  1  2  3  4  5  6  7  8  9 10 11 12 25 24 23 22 21 20 19 18 17 16 15 14 13 26 27 28 29 30 31 32 33 34 35 36 37 38 39
571
572 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
573 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
574 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
575 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 55 56 57 58 59 60 61 62 63 64 65 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
576
577 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
578 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
579 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
580 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
581
582
583 // LO   h   e   l   l   o   _   w   o   r   l   d
584 //     96  97  98  99 100 101 102 103 104 105 106
585 // VO   h   e   l   l   o   _   w   o   r   l   d
586 //     96  97  98  99 100 101 102 103 104 105 106
587
588   unsigned int visualToLogical05[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
589   unsigned int  cachedBidiLine05[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u };
590
591 // size 300, 300
592 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
593 //      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
594 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _  م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
595 //      0  1  2  3  4  5  6  7  8  9 10 11 12 25 24 23 22 21 20 19 18 17 16 15 14 13 26 27
596
597 // LO    h  e  l  l  o  _  w  o  r  l  d \n
598 //      28 29 30 31 32 33 34 35 36 37 38 39
599 // VO    h  e  l  l  o  _  w  o  r  l  d \n
600 //      28 29 30 31 32 33 34 35 36 37 38 39
601
602 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _  h  e  l  l  o  _  w  o  r  l  d   ,  _
603 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
604 // VO  _  ,  h  e  l  l  o  _  w  o  r  l  d   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
605 //     67 66 55 56 57 58 59 60 61 62 63 64 65 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
606
607 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
608 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
609 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
610 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
611
612 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
613 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
614 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
615 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
616
617
618 // LO   h   e   l   l   o   _   w   o   r   l   d
619 //     96  97  98  99 100 101 102 103 104 105 106
620 // VO   h   e   l   l   o   _   w   o   r   l   d
621 //     96  97  98  99 100 101 102 103 104 105 106
622
623   unsigned int visualToLogical06[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u, 12u, 25u, 24u, 23u, 22u, 21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u, 43u, 42u, 41u, 40u, 67u, 66u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 81u, 80u, 79u, 78u, 77u, 76u, 75u, 74u, 73u, 72u, 71u, 70u, 69u, 68u, 95u, 94u, 93u, 92u, 91u, 90u, 89u, 88u, 87u, 86u, 85u, 84u, 83u, 82u, 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, 104u, 105u, 106u };
624   unsigned int  cachedBidiLine06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
625                                        0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
626                                        1u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u,
627                                        2u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
628                                        3u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u,
629                                        4u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u,
630                                        5u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u,
631                                        6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u, 6u };
632
633 // size 100, 600
634 // LO   H  e  l  l  o  _  w  o  r  l  d  ,  _
635 //      0  1  2  3  4  5  6  7  8  9 10 11 12
636 // VO   H  e  l  l  o  _  w  o  r  l  d  ,  _
637 //      0  1  2  3  4  5  6  7  8  9 10 11 12
638
639 // LO    م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,   _
640 //      13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
641 // VO    م  ل  ا  ع   ل  ا  ب  _  ا   ب  ح  ر  م  ,   _
642 //      25 24 23 22 21 20 19 18 17 16 15 14 13 26 27
643
644 // LO    h  e  l  l  o  _  w  o  r  l  d \n
645 //      28 29 30 31 32 33 34 35 36 37 38 39
646 // VO    h  e  l  l  o  _  w  o  r  l  d \n
647 //      28 29 30 31 32 33 34 35 36 37 38 39
648
649 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  ,  _
650 //     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
651 // VO   _  ,  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
652 //     54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
653
654 // LO   h  e  l  l  o  _  w  o  r  l  d   ,  _
655 //     55 56 57 58 59 60 61 62 63 64 65 66 67
656 // VO   _  ,  h  e  l  l  o  _  w  o  r  l  d
657 //     67 66 55 56 57 58 59 60 61 62 63 64 65
658
659 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
660 //     68 69 70 71 72 73 74 75 76 77 78 79 80 81
661 // VO  \n  م  ل  ا   ع  ل  ا  ب  _  ا   ب  ح  ر  م
662 //     81 80 79 78 77 76 75 74 73 72 71 70 69 68
663
664 // LO   م  ر  ح  ب   ا  _  ب  ا  ل  ع   ا  ل  م  \n
665 //     82 83 84 85 86 87 88 89 90 91 92 93 94 95
666 // VO  \n  م  ل  ا  ع  ل   ا  ب  _  ا   ب  ح  ر  م
667 //     95 94 93 92 91 90 89 88 87 86 85 84 83 82
668
669
670 // LO   h   e   l   l   o   _   w   o   r   l   d
671 //     96  97  98  99 100 101 102 103 104 105 106
672 // VO   h   e   l   l   o   _   w   o   r   l   d
673 //     96  97  98  99 100 101 102 103 104 105 106
674
675   struct GetLogicalCharacterIndexData data[] =
676   {
677     {
678       "Zero characters text",
679       "",
680       Size( 300.f, 300.f ),
681       0u,
682       visualToLogical01,
683       cachedBidiLine01
684     },
685     {
686       "Left to right text only",
687       "Hello world",
688       Size( 300.f, 300.f ),
689       11u,
690       visualToLogical02,
691       cachedBidiLine02
692     },
693     {
694       "Right to left text only",
695       "مرحبا بالعالم",
696       Size( 300.f, 300.f ),
697       13u,
698       visualToLogical03,
699       cachedBidiLine03
700     },
701     {
702       "Mix of left to right and right to left text.",
703       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
704       Size( 300.f, 300.f ),
705       107u,
706       visualToLogical04,
707       cachedBidiLine04
708     },
709     {
710       "Mix of left to right and right to left text.",
711       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
712       Size( 200.f, 400.f ),
713       107u,
714       visualToLogical05,
715       cachedBidiLine05
716     },
717     {
718       "Mix of left to right and right to left text.",
719       "Hello world, مرحبا بالعالم, hello world\nمرحبا بالعالم, hello world, مرحبا بالعالم\nمرحبا بالعالم\nhello world",
720       Size( 100.f, 600.f ),
721       107u,
722       visualToLogical06,
723       cachedBidiLine06
724     },
725   };
726   const unsigned int numberOfTests = 6u;
727
728   for( unsigned int index = 0u; index < numberOfTests; ++index )
729   {
730     ToolkitTestApplication application;
731     if( !GetLogicalCharacterIndexTest( data[index] ) )
732     {
733       tet_result(TET_FAIL);
734     }
735   }
736
737   tet_result(TET_PASS);
738   END_TEST;
739 }
740
741 int UtcDaliGetLogicalCursorIndex(void)
742 {
743   tet_infoline(" UtcDaliGetLogicalCursorIndex");
744
745   unsigned int visualIndex01[] = { 10u };
746   unsigned int characterIndex01[] = { 0u };
747   unsigned int logicalIndex01[] = { 10u };
748   unsigned int bidirectionalLineIndex01[] = { 0u };
749
750   //  0           11
751   //   Hello world  \n
752   // 12    16
753   //   demo
754   unsigned int visualIndex02[] = { 0u, 16u, 11u, 12u };
755   unsigned int characterIndex02[] = { 0u, 0u, 0u, 0u };
756   unsigned int logicalIndex02[] = { 0u, 16u, 11u, 12u };
757   unsigned int bidirectionalLineIndex02[] = { 0u, 0u, 0u, 0u };
758
759
760 // LO     H  e  l  l  o  _  w  o  r  l  d  \n
761 //       0  1  2  3  4  5  6  7  8  9 10 11  12
762 // VO     H  e  l  l  o  _  w  o  r  l  d  \n
763
764 // LO         ש  ל  ו  ם  _  ע  ו  ל  ם \n
765 //          12 13 14 15 16 17 18 19 20 21  22
766 // VO     \n  ם  ל  ו  ע _  ם  ו  ל  ש
767
768 // LO      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע ו  ל  ם  \n
769 //       22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43  44
770 // VO      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש  \n
771
772 // LO      ש  ל  ו  ם  _  ע  ו  ל  ם  _  h  e  l  l  o  _  w  o  r   l  d \n
773 //       44 45 46 47 48 49 50 51  52 52 54 55 56 57 58 59 60 61 62 63  64 65 66
774 // VO      \n h  e  l  l  o  _  w   o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
775
776   unsigned int visualIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
777                                    13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u,
778                                    22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u,
779                                    45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u, 66u };
780
781   unsigned int characterIndex03[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
782                                       12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u, 12u,
783                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
784                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u};
785
786   unsigned int logicalIndex03[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
787                                     21u, 20u, 19u, 18u, 17u, 16u, 15u, 14u, 13u, 12u,
788                                     22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 42u, 41u, 40u, 39u, 38u, 37u, 36u, 35u, 43u,
789                                     65u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 54u, 53u, 52u, 51u, 50u, 49u, 48u, 47u, 46u, 45u, 44u };
790
791   unsigned int bidirectionalLineIndex03[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
792                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
793                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
794                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
795
796
797 // LO     ש  ל  ו  ם  _  ע  ו  ל  ם \n
798 //       0  1  2  3  4  5  6  7  8  9 10
799 // VO  \n ם  ל  ו  ע  _  ם  ו  ל  ש
800
801 //      h  e  l  l  o  _  w  o  r  l  d  \n
802 // LO 10 11 12 13 14 15 16 17 18 19 20 21 22
803 //      h  e  l  l  o  _  w  o  r  l  d  \n
804
805 //         ש  ל  ו  ם  _  ע  ו  ל  ם _  h  e  l  l  o  _  w  o  r  l  d  \n
806 // LO    22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
807 //     \n  h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש
808
809 //      h  e  l  l  o  _  w  o  r  l  d  _  ש  ל  ו  ם  _  ע  ו  ל  ם \n
810 // LO 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
811 //      h  e  l  l  o  _  w  o  r  l  d  _  ם  ל  ו  ע  _  ם  ו  ל  ש \n
812
813   unsigned int  visualIndex04[] = {  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
814                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
815                                     23u, 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 43u, 44u,
816                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, 64u, 65u };
817
818   unsigned int characterIndex04[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
819                                       10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 10u,
820                                       22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u, 22u,
821                                       44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u, 44u };
822
823   unsigned int logicalIndex04[] = {  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u,  0u,
824                                     10u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u,
825                                     43u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, 41u, 42u, 32u, 31u, 30u, 29u, 28u, 27u, 26u, 25u, 24u, 23u, 22u,
826                                     44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 64u, 63u, 62u, 61u, 60u, 59u, 58u, 57u, 65u };
827
828   unsigned int bidirectionalLineIndex04[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
829                                               0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
830                                               1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u,
831                                               2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u, 2u };
832
833
834 // LO   A  B  C  D  E  F  G  H  I  J  K
835 //     0  1  2  3  4  5  6  7  8  9 10 11
836 // LO   L  M  N
837 //    11 12 13 14
838
839   unsigned int  visualIndex05[] = {  0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
840                                     11u, 12u, 13u, 14u };
841
842   unsigned int characterIndex05[] = { 0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
843                                       11u, 11u, 11u, 11u };
844
845   unsigned int logicalIndex05[] = { 0u,  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u,
846                                     11u, 12u, 13u, 14u };
847
848   unsigned int bidirectionalLineIndex05[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
849                                               0u, 0u, 0u, 0u };
850
851 // LO      ק  ר  א  ט  ו  ן  ם  פ  ש  ד  ג
852 //        0  1  2  3  4  5  6  7  8  9  10 11
853 // VO      ג  ד  ש  פ  ם  ן  ו  ט  א  ר  ק
854
855 // LO      כ  ע  י  ח  ל
856 //       11 12 13 14 15 16
857 // VO      ל  ח  י  ע  כ
858
859   unsigned int  visualIndex06[] = {  1u,  2u,  3u,  4u,  5u,  6u,  7u,  8u,  9u, 10u, 11u,
860                                     11u, 12u, 13u, 14u, 15u, 16u };
861
862   unsigned int characterIndex06[] = {  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,  0u,
863                                       12u, 12u, 12u, 12u, 12u, 12u };
864
865   unsigned int logicalIndex06[] = { 10u,  9u,  8u,  7u,  6u,  5u,  4u,  3u,  2u,  1u,  0u,
866                                     16u, 15u, 14u, 13u, 12u, 11u };
867
868   unsigned int bidirectionalLineIndex06[] = { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
869                                               1u, 1u, 1u, 1u, 1u, 1u };
870
871   struct GetLogicalCursorIndexData data[] =
872   {
873     {
874       "Zero characters text",
875       "",
876       Size( 300.f, 300.f ),
877       1u,
878       visualIndex01,
879       characterIndex01,
880       logicalIndex01,
881       bidirectionalLineIndex01,
882     },
883     {
884       "All left to right text 01.",
885       "Hello world\ndemo",
886       Size( 300.f, 300.f ),
887       4u,
888       visualIndex02,
889       characterIndex02,
890       logicalIndex02,
891       bidirectionalLineIndex02,
892     },
893     {
894       "bidirectional text 01.",
895       "Hello world\nשלום עולם\nhello world שלום עולם\nשלום עולם hello world\n",
896       Size( 300.f, 300.f ),
897       65u,
898       visualIndex03,
899       characterIndex03,
900       logicalIndex03,
901       bidirectionalLineIndex03,
902     },
903     {
904       "bidirectional text 02.",
905       "שלום עולם\nhello world\nשלום עולם hello world\nhello world שלום עולם\n",
906       Size( 300.f, 300.f ),
907       65u,
908       visualIndex04,
909       characterIndex04,
910       logicalIndex04,
911       bidirectionalLineIndex04,
912     },
913     {
914       "long line 01.",
915       "ABCDEFGHIJKLMN",
916       Size( 100.f, 300.f ),
917       13u,
918       visualIndex05,
919       characterIndex05,
920       logicalIndex05,
921       bidirectionalLineIndex05,
922     },
923     {
924       "bidirectional text 03.",
925       "קראטוןםפשדגכעיחל",
926       Size( 100.f, 300.f ),
927       15u,
928       visualIndex06,
929       characterIndex06,
930       logicalIndex06,
931       bidirectionalLineIndex06,
932     },
933   };
934   const unsigned int numberOfTests = 6u;
935
936   for( unsigned int index = 0u; index < numberOfTests; ++index )
937   {
938     ToolkitTestApplication application;
939     if( !GetLogicalCursorIndexTest( data[index] ) )
940     {
941       tet_result(TET_FAIL);
942     }
943   }
944
945   tet_result(TET_PASS);
946   END_TEST;
947 }