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