[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-IndexedConstStringMap.cpp
1 /*
2  * Copyright (c) 2023 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 <dali-test-suite-utils.h>
19 #include <dali/public-api/dali-core.h>
20
21 #include <random>
22 #include <string>
23
24 // Internal headers are allowed here
25 #include <dali/internal/common/indexed-const-string-map.h>
26
27 using namespace Dali;
28 using Dali::Internal::ConstString;
29 using Dali::Internal::IndexedConstStringMap;
30 namespace
31 {
32 std::string RandomString(size_t length)
33 {
34   static auto& chrs =
35     "0123456789"
36     "abcdefghijklmnopqrstuvwxyz"
37     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
38
39   thread_local static std::mt19937                                          rg{std::random_device{}()};
40   thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
41
42   std::string s;
43
44   s.reserve(length);
45
46   while(length--)
47     s += chrs[pick(rg)];
48
49   return s;
50 }
51
52 } // namespace
53
54 // Custom DALI_TEST_EQUALS for ConstString
55 template<>
56 inline void DALI_TEST_EQUALS<ConstString>(ConstString str1, ConstString str2, const char* location)
57 {
58   DALI_TEST_EQUALS(str1.GetStringView(), str2.GetStringView(), location);
59 }
60
61 void utc_dali_internal_indexed_conststring_map_startup(void)
62 {
63   test_return_value = TET_UNDEF;
64 }
65
66 void utc_dali_internal_indexed_conststring_map_cleanup(void)
67 {
68   test_return_value = TET_PASS;
69 }
70
71 int UtcDaliIndexedConstStringMapEmpty(void)
72 {
73   IndexedConstStringMap<int> indexedMap;
74   DALI_TEST_EQUALS(indexedMap.Empty(), true, TEST_LOCATION);
75   DALI_TEST_EQUALS(indexedMap.empty(), true, TEST_LOCATION);
76
77   ConstString str("hello");
78   int         value = 3;
79   DALI_TEST_EQUALS(indexedMap.Register(str, value), true, TEST_LOCATION);
80
81   DALI_TEST_EQUALS(indexedMap.Empty(), false, TEST_LOCATION);
82   DALI_TEST_EQUALS(indexedMap.empty(), false, TEST_LOCATION);
83
84   DALI_TEST_EQUALS(indexedMap.Count(), 1, TEST_LOCATION);
85   DALI_TEST_EQUALS(indexedMap.size(), 1, TEST_LOCATION);
86
87   DALI_TEST_EQUALS(indexedMap.Get(str)->first, str, TEST_LOCATION);
88   DALI_TEST_EQUALS(indexedMap.Get(str)->second, value, TEST_LOCATION);
89
90   indexedMap.Clear();
91   DALI_TEST_EQUALS(indexedMap.Empty(), true, TEST_LOCATION);
92   DALI_TEST_EQUALS(indexedMap.empty(), true, TEST_LOCATION);
93
94   DALI_TEST_CHECK(indexedMap.Get(str) == indexedMap.End());
95
96   END_TEST;
97 }
98
99 int UtcDaliIndexedConstStringMap(void)
100 {
101   IndexedConstStringMap<int> indexedMap;
102
103   auto IndexedMapGetValueTest = [](const IndexedConstStringMap<int>& indexedMap, ConstString key, bool registered, int element, const char* location) {
104     const auto& iter = indexedMap.Get(key);
105     DALI_TEST_EQUALS(!(iter == indexedMap.end()), registered, location);
106     if(registered)
107     {
108       DALI_TEST_EQUALS(iter->second, element, location);
109     }
110   };
111
112   ConstString keyFirst  = ConstString("first");
113   ConstString keySecond = ConstString("second");
114   ConstString keyThird  = ConstString("third");
115   ConstString keyFourth = ConstString("fourth");
116
117   // Check. empty state
118   DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
119   DALI_TEST_CHECK(indexedMap.Begin() == indexedMap.End());
120   DALI_TEST_CHECK(indexedMap.Empty());
121   DALI_TEST_EQUALS(0u, indexedMap.size(), TEST_LOCATION);
122   DALI_TEST_CHECK(indexedMap.begin() == indexedMap.end());
123   DALI_TEST_CHECK(indexedMap.empty());
124
125   // phase 1 - Regist two element
126   DALI_TEST_CHECK(indexedMap.Register(keyFirst, 1));
127   DALI_TEST_CHECK(indexedMap.Register(keySecond, 2));
128
129   // Get data by key
130   DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
131   DALI_TEST_CHECK(!indexedMap.Empty());
132   IndexedMapGetValueTest(indexedMap, ConstString("first"), true, 1, TEST_LOCATION);
133   IndexedMapGetValueTest(indexedMap, ConstString("second"), true, 2, TEST_LOCATION);
134   IndexedMapGetValueTest(indexedMap, ConstString("third"), false, 0, TEST_LOCATION);
135   IndexedMapGetValueTest(indexedMap, ConstString("fourth"), false, 0, TEST_LOCATION);
136
137   // Get data by index
138   DALI_TEST_EQUALS(indexedMap[keyFirst], 1, TEST_LOCATION);
139   DALI_TEST_EQUALS(indexedMap[keySecond], 2, TEST_LOCATION);
140   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 1, TEST_LOCATION);
141   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 2, TEST_LOCATION);
142   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
143   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
144   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 1));
145   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 2));
146
147   // Const iteration check
148   for(const auto& elem : indexedMap)
149   {
150     if(elem.first == keyFirst)
151     {
152       DALI_TEST_EQUALS(elem.second, 1, TEST_LOCATION);
153     }
154     else if(elem.first == keySecond)
155     {
156       DALI_TEST_EQUALS(elem.second, 2, TEST_LOCATION);
157     }
158     else
159     {
160       DALI_TEST_CHECK(false); // Should not get here
161     }
162   }
163
164   // Iteration and fix data check
165   for(auto&& elem : indexedMap)
166   {
167     if(elem.first == keyFirst)
168     {
169       elem.second += 110;
170     }
171   }
172   // operator[] fix data check
173   indexedMap[keySecond] += 220;
174
175   // Get data by key
176   DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
177   IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
178   IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
179   IndexedMapGetValueTest(indexedMap, keyThird, false, 0, TEST_LOCATION);
180   IndexedMapGetValueTest(indexedMap, keyFourth, false, 0, TEST_LOCATION);
181
182   // Get data by index
183   DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
184   DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
185   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
186   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
187   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
188   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
189   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 111));
190   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 222));
191
192   // Const iteration check
193   for(const auto& elem : indexedMap)
194   {
195     if(elem.first == keyFirst)
196     {
197       DALI_TEST_EQUALS(elem.second, 111, TEST_LOCATION);
198     }
199     else if(elem.first == keySecond)
200     {
201       DALI_TEST_EQUALS(elem.second, 222, TEST_LOCATION);
202     }
203     else
204     {
205       DALI_TEST_CHECK(false); // Should not get here
206     }
207   }
208
209   // phase 2 - Regist two more element
210   DALI_TEST_CHECK(!indexedMap.Register(keyFirst, 11));  // Register failed when we try to insert data with same key
211   DALI_TEST_CHECK(!indexedMap.Register(keySecond, 22)); // Register failed when we try to insert data with same key
212   DALI_TEST_CHECK(indexedMap.Register(keyThird, 3));
213   DALI_TEST_CHECK(indexedMap.Register(keyFourth, 4));
214
215   // Get data by key
216   DALI_TEST_EQUALS(4, indexedMap.Count(), TEST_LOCATION);
217   IndexedMapGetValueTest(indexedMap, keyFirst, true, 111, TEST_LOCATION);
218   IndexedMapGetValueTest(indexedMap, keySecond, true, 222, TEST_LOCATION);
219   IndexedMapGetValueTest(indexedMap, keyThird, true, 3, TEST_LOCATION);
220   IndexedMapGetValueTest(indexedMap, keyFourth, true, 4, TEST_LOCATION);
221
222   // Get elemnt as l-value
223   {
224     auto iter = indexedMap.Get(keyFourth);
225     DALI_TEST_CHECK(iter != indexedMap.end())
226     {
227       iter->second = 444;
228     }
229   }
230
231   // Get data by index
232   DALI_TEST_EQUALS(indexedMap[keyFirst], 111, TEST_LOCATION);
233   DALI_TEST_EQUALS(indexedMap[keySecond], 222, TEST_LOCATION);
234   DALI_TEST_EQUALS(indexedMap[keyThird], 3, TEST_LOCATION);
235   DALI_TEST_EQUALS(indexedMap[keyFourth], 444, TEST_LOCATION);
236   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(0), 111, TEST_LOCATION);
237   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(1), 222, TEST_LOCATION);
238   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(2), 3, TEST_LOCATION);
239   DALI_TEST_EQUALS(indexedMap.GetElementByIndex(3), 444, TEST_LOCATION);
240   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(0), keyFirst, TEST_LOCATION);
241   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(1), keySecond, TEST_LOCATION);
242   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(2), keyThird, TEST_LOCATION);
243   DALI_TEST_EQUALS(indexedMap.GetKeyByIndex(3), keyFourth, TEST_LOCATION);
244   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(0) == IndexedConstStringMap<int>::KeyElementPairType(keyFirst, 111));
245   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(1) == IndexedConstStringMap<int>::KeyElementPairType(keySecond, 222));
246   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(2) == IndexedConstStringMap<int>::KeyElementPairType(keyThird, 3));
247   DALI_TEST_CHECK(indexedMap.GetKeyElementPairByIndex(3) == IndexedConstStringMap<int>::KeyElementPairType(keyFourth, 444));
248
249   // For coverage
250   DALI_TEST_EQUALS(const_cast<const IndexedConstStringMap<int>&>(indexedMap)[keyFirst], 111, TEST_LOCATION);
251
252   // Clear check
253   DALI_TEST_CHECK(!indexedMap.Empty());
254   indexedMap.Clear();
255   DALI_TEST_CHECK(indexedMap.Empty());
256   DALI_TEST_EQUALS(0u, indexedMap.Count(), TEST_LOCATION);
257   IndexedMapGetValueTest(indexedMap, keyFirst, false, 1, TEST_LOCATION);
258   IndexedMapGetValueTest(indexedMap, keySecond, false, 2, TEST_LOCATION);
259   IndexedMapGetValueTest(indexedMap, keyThird, false, 3, TEST_LOCATION);
260   IndexedMapGetValueTest(indexedMap, keyFourth, false, 4, TEST_LOCATION);
261
262   END_TEST;
263 }
264
265 int UtcDaliIndexedConstStringMapNegative(void)
266 {
267   tet_infoline("Negative test when IndexedConstStringMap access non-exist elements.");
268
269   IndexedConstStringMap<int> indexedMap;
270
271   auto IndexedMapAssertTestWithIndex = [](IndexedConstStringMap<int>& indexedMap, int testIndex) {
272     tet_printf("operator[] test");
273     // Assert when try to access as const operator[] input with not registered key.
274     try
275     {
276       const auto& elem = const_cast<const IndexedConstStringMap<int>&>(indexedMap)[ConstString("333")];
277       if(elem == 0) // Avoid build warning
278       {
279         DALI_TEST_CHECK(false); // Should not get here
280       }
281       DALI_TEST_CHECK(false); // Should not get here
282     }
283     catch(...)
284     {
285       DALI_TEST_CHECK(true); // Asserted
286     }
287     // Assert when try to access as operator[] input with not registered key.
288     try
289     {
290       indexedMap[ConstString("333")] = 0;
291       DALI_TEST_CHECK(false); // Should not get here
292     }
293     catch(...)
294     {
295       DALI_TEST_CHECK(true); // Asserted
296     }
297
298     tet_printf("GetElementByIndex test");
299     // Assert when try to access as GetElementByIndex input with not registered index.
300     try
301     {
302       const auto& elem = indexedMap.GetElementByIndex(testIndex);
303       if(elem == 0) // Avoid build warning
304       {
305         DALI_TEST_CHECK(false); // Should not get here
306       }
307       DALI_TEST_CHECK(false); // Should not get here
308     }
309     catch(...)
310     {
311       DALI_TEST_CHECK(true); // Asserted
312     }
313
314     tet_printf("GetKeyByIndex test");
315     // Assert when try to access as GetKeyByIndex input with not registered index.
316     try
317     {
318       const auto& elem = indexedMap.GetKeyByIndex(testIndex);
319       if(elem == 0) // Avoid build warning
320       {
321         DALI_TEST_CHECK(false); // Should not get here
322       }
323       DALI_TEST_CHECK(false); // Should not get here
324     }
325     catch(...)
326     {
327       DALI_TEST_CHECK(true); // Asserted
328     }
329
330     tet_printf("GetKeyElementPairByIndex test");
331     // Assert when try to access as GetKeyByIndex input with not registered index.
332     try
333     {
334       const auto& elem = indexedMap.GetKeyElementPairByIndex(testIndex);
335       if(elem == IndexedConstStringMap<int>::KeyElementPairType(ConstString("zero"), 0)) // Avoid build warning
336       {
337         DALI_TEST_CHECK(false); // Should not get here
338       }
339       DALI_TEST_CHECK(false); // Should not get here
340     }
341     catch(...)
342     {
343       DALI_TEST_CHECK(true); // Asserted
344     }
345   };
346   // Assert test with empty indexedMap.
347   DALI_TEST_CHECK(indexedMap.Empty());
348   IndexedMapAssertTestWithIndex(indexedMap, 0);
349
350   // Register 2 data
351   DALI_TEST_CHECK(indexedMap.Register(ConstString("first"), 1));
352   DALI_TEST_CHECK(indexedMap.Register(ConstString("second"), 2));
353   DALI_TEST_EQUALS(2u, indexedMap.Count(), TEST_LOCATION);
354   IndexedMapAssertTestWithIndex(indexedMap, 2);
355
356   // Test with always-invalid index like -1
357   IndexedMapAssertTestWithIndex(indexedMap, -1);
358
359   END_TEST;
360 }
361
362 int UtcDaliIndexedConstStringMapStressTest(void)
363 {
364   // Copy from utc-Dali-Internal-ConstString.cpp
365   static constexpr size_t DB_SIZE = 2000;
366
367   std::vector<std::string> Database;
368   Database.reserve(DB_SIZE);
369
370   IndexedConstStringMap<ConstString> constStringDB1;
371   constStringDB1.reserve(DB_SIZE);
372
373   IndexedConstStringMap<std::string> constStringDB2;
374   constStringDB2.reserve(DB_SIZE);
375
376   for(auto i = 0u; i < DB_SIZE; i++)
377   {
378     if(i % 3 == 0)
379     {
380       Database.push_back(RandomString(10));
381     }
382     else if(i % 4 == 0)
383     {
384       Database.push_back(RandomString(7));
385     }
386     else
387     {
388       Database.push_back(RandomString(11));
389     }
390     std::string randomValue = RandomString(10);
391     DALI_TEST_EQUALS(constStringDB1.Register(ConstString(Database[i]), ConstString(randomValue)), true, TEST_LOCATION);
392     DALI_TEST_EQUALS(constStringDB2.Register(ConstString(Database[i]), randomValue), true, TEST_LOCATION);
393   }
394
395   // Try to extra regist with same key
396   for(auto i = 0u; i < DB_SIZE; i++)
397   {
398     std::string randomValue = RandomString(2);
399     DALI_TEST_EQUALS(constStringDB1.Register(ConstString(Database[i]), ConstString(randomValue)), false, TEST_LOCATION);
400     DALI_TEST_EQUALS(constStringDB2.Register(ConstString(Database[i]), randomValue), false, TEST_LOCATION);
401   }
402
403   // check eqality betwwen original string and constString
404   for(auto i = 0u; i < DB_SIZE; i++)
405   {
406     DALI_TEST_EQUALS(constStringDB1.GetKeyByIndex(i).GetCString(), Database[i].c_str(), TEST_LOCATION);
407     DALI_TEST_EQUALS(constStringDB2.GetKeyByIndex(i).GetCString(), Database[i].c_str(), TEST_LOCATION);
408   }
409
410   // check pointer eqality betwwen 2 constString
411   for(auto i = 0u; i < DB_SIZE; i++)
412   {
413     bool pointerEqual = (constStringDB1[ConstString(Database[i])] == ConstString(constStringDB2[ConstString(Database[i])]));
414     DALI_TEST_EQUALS(pointerEqual, true, TEST_LOCATION);
415   }
416
417   END_TEST;
418 }
419
420 int UtcDaliIndexedConstStringMapMoveTest(void)
421 {
422   IndexedConstStringMap<std::string> indexedMap;
423
424   std::string expectString = "wahaha";
425
426   std::string p = expectString; // copy string;
427   DALI_TEST_CHECK(indexedMap.Register(ConstString("111"), p));
428   DALI_TEST_CHECK(!indexedMap.Register(ConstString("111"), p));
429
430   DALI_TEST_EQUALS(p, expectString, TEST_LOCATION);
431   DALI_TEST_EQUALS(indexedMap[ConstString("111")], expectString, TEST_LOCATION);
432
433   // Change expect string
434   expectString = "wehihi";
435   p            = expectString;
436
437   DALI_TEST_CHECK(indexedMap.Register(ConstString("222"), std::move(p)));
438
439   DALI_TEST_CHECK(p.empty()); // string moved.
440   DALI_TEST_EQUALS(indexedMap[ConstString("222")], expectString, TEST_LOCATION);
441
442   p = expectString;
443
444   DALI_TEST_CHECK(!indexedMap.Register(ConstString("222"), std::move(p)));
445
446   END_TEST;
447 }