@@ -220,4 +220,84 @@ TEST_CASE(CStringMap) {
220
220
free (str1);
221
221
}
222
222
223
+ TEST_CASE (CStringMapUpdate) {
224
+ const char * const kConst1 = " test" ;
225
+ const char * const kConst2 = " test 2" ;
226
+
227
+ char * str1 = OS::SCreate (nullptr , " %s" , kConst1 );
228
+ char * str2 = OS::SCreate (nullptr , " %s" , kConst2 );
229
+ char * str3 = OS::SCreate (nullptr , " %s" , kConst1 );
230
+ char * str4 = OS::SCreate (nullptr , " %s" , kConst1 ); // Only used for lookup.
231
+
232
+ // Make sure these strings are pointer-distinct, but C-string-equal.
233
+ EXPECT_NE (str1, str3);
234
+ EXPECT_NE (str1, str4);
235
+ EXPECT_NE (str3, str4);
236
+ EXPECT_STREQ (str1, str3);
237
+ EXPECT_STREQ (str1, str4);
238
+
239
+ CStringKeyValueTrait<intptr_t >::Pair p1 = {str1, 1 };
240
+ CStringKeyValueTrait<intptr_t >::Pair p2 = {str2, 2 };
241
+ CStringKeyValueTrait<intptr_t >::Pair p3 = {str3, 3 };
242
+
243
+ CStringMap<intptr_t > map;
244
+ EXPECT (map.IsEmpty ());
245
+
246
+ map.Update (p1);
247
+ EXPECT_NOTNULL (map.Lookup (str1));
248
+ EXPECT_EQ (p1.value , map.LookupValue (str1));
249
+ EXPECT_NULLPTR (map.Lookup (str2));
250
+ EXPECT_NOTNULL (map.Lookup (str3));
251
+ EXPECT_EQ (p1.value , map.LookupValue (str3));
252
+ EXPECT_NOTNULL (map.Lookup (str4));
253
+ EXPECT_EQ (p1.value , map.LookupValue (str4));
254
+
255
+ map.Update (p2);
256
+ EXPECT_NOTNULL (map.Lookup (str1));
257
+ EXPECT_EQ (p1.value , map.LookupValue (str1));
258
+ EXPECT_NOTNULL (map.Lookup (str2));
259
+ EXPECT_EQ (p2.value , map.LookupValue (str2));
260
+ EXPECT_NOTNULL (map.Lookup (str3));
261
+ EXPECT_EQ (p1.value , map.LookupValue (str3));
262
+ EXPECT_NOTNULL (map.Lookup (str4));
263
+ EXPECT_EQ (p1.value , map.LookupValue (str4));
264
+
265
+ // Check Lookup after Update.
266
+ map.Update (p3);
267
+ EXPECT_NOTNULL (map.Lookup (str1));
268
+ EXPECT_EQ (p3.value , map.LookupValue (str1));
269
+ EXPECT_NOTNULL (map.Lookup (str2));
270
+ EXPECT_EQ (p2.value , map.LookupValue (str2));
271
+ EXPECT_NOTNULL (map.Lookup (str3));
272
+ EXPECT_EQ (p3.value , map.LookupValue (str3));
273
+ EXPECT_NOTNULL (map.Lookup (str4));
274
+ EXPECT_EQ (p3.value , map.LookupValue (str4));
275
+
276
+ // Check that single Remove after only Updates ensures Lookup fails after.
277
+ EXPECT (map.Remove (str3));
278
+ EXPECT_NULLPTR (map.Lookup (str1));
279
+ EXPECT_NOTNULL (map.Lookup (str2));
280
+ EXPECT_EQ (p2.value , map.LookupValue (str2));
281
+ EXPECT_NULLPTR (map.Lookup (str3));
282
+ EXPECT_NULLPTR (map.Lookup (str4));
283
+
284
+ EXPECT (!map.Remove (str3));
285
+ EXPECT (map.Remove (str2));
286
+ EXPECT (map.IsEmpty ());
287
+
288
+ // Quick double-check that these weren't side-effected by the implementation
289
+ // of hash maps (p1 especially).
290
+ EXPECT_EQ (str1, p1.key );
291
+ EXPECT_EQ (1 , p1.value );
292
+ EXPECT_EQ (str2, p2.key );
293
+ EXPECT_EQ (2 , p2.value );
294
+ EXPECT_EQ (str3, p3.key );
295
+ EXPECT_EQ (3 , p3.value );
296
+
297
+ free (str4);
298
+ free (str3);
299
+ free (str2);
300
+ free (str1);
301
+ }
302
+
223
303
} // namespace dart
0 commit comments