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