@@ -250,10 +250,10 @@ suite async_map_tests = [] {
250
250
std::cout << it->second << ' \n ' ;
251
251
}
252
252
};
253
+
254
+ static_assert (glz::detail::readable_map_t <glz::async_map<std::string, std::atomic<int >>>);
253
255
254
256
" async_map write_json" _test = [] {
255
- static_assert (glz::detail::readable_map_t <glz::async_map<std::string, std::atomic<int >>>);
256
-
257
257
glz::async_map<std::string, std::atomic<int >> map;
258
258
map[" one" ] = 1 ;
259
259
map[" two" ] = 2 ;
@@ -267,6 +267,157 @@ suite async_map_tests = [] {
267
267
expect (map.at (" one" ).value () == 1 );
268
268
expect (map.at (" two" ).value () == 2 );
269
269
};
270
+
271
+ // Test serialization and deserialization of an empty async_map
272
+ " async_map empty" _test = [] {
273
+ glz::async_map<std::string, std::atomic<int >> map;
274
+
275
+ // Serialize the empty map
276
+ std::string buffer{};
277
+ expect (not glz::write_json (map, buffer));
278
+ expect (buffer == R"( {})" ) << buffer;
279
+
280
+ // Clear and deserialize back
281
+ map.clear ();
282
+ expect (not glz::read_json (map, buffer));
283
+ expect (map.empty ());
284
+ };
285
+
286
+ // Test handling of keys and values with special characters
287
+ " async_map special_characters" _test = [] {
288
+ glz::async_map<std::string, std::atomic<int >> map;
289
+ map[" key with spaces" ] = 42 ;
290
+ map[" key_with_\" quotes\" " ] = 84 ;
291
+ map[" ключ" ] = 168 ; // "key" in Russian
292
+
293
+ std::string buffer{};
294
+ expect (not glz::write_json (map, buffer));
295
+
296
+ // Expected JSON with properly escaped characters
297
+ std::string expected = R"( {"key with spaces":42,"key_with_\"quotes\"":84,"ключ":168})" ;
298
+ expect (buffer == expected) << buffer;
299
+
300
+ // Deserialize and verify
301
+ map.clear ();
302
+ expect (not glz::read_json (map, buffer));
303
+ expect (map.at (" key with spaces" ).value () == 42 );
304
+ expect (map.at (" key_with_\" quotes\" " ).value () == 84 );
305
+ expect (map.at (" ключ" ).value () == 168 );
306
+ };
307
+
308
+ // Test serialization and deserialization of a large async_map
309
+ " async_map large_map" _test = [] {
310
+ glz::async_map<int , std::atomic<int >> map;
311
+
312
+ // Populate the map with 1000 entries
313
+ for (int i = 0 ; i < 1000 ; ++i) {
314
+ map[i] = i * i;
315
+ }
316
+
317
+ std::string buffer{};
318
+ expect (not glz::write_json (map, buffer));
319
+
320
+ // Simple check to ensure buffer is not empty
321
+ expect (!buffer.empty ());
322
+
323
+ // Deserialize and verify a few entries
324
+ map.clear ();
325
+ expect (not glz::read_json (map, buffer));
326
+ expect (map.size () == 1000 );
327
+ expect (map.at (0 ).value () == 0 );
328
+ expect (map.at (999 ).value () == 999 * 999 );
329
+ };
330
+
331
+ // Test deserialization with invalid JSON
332
+ " async_map invalid_json" _test = [] {
333
+ glz::async_map<std::string, std::atomic<int >> map;
334
+ std::string invalid_buffer = R"( {"one":1, "two": "invalid_value"})" ; // "two" should be an integer
335
+
336
+ expect (glz::read_json (map, invalid_buffer)); // Expecting an error (assuming 'read_json' returns true on failure)
337
+ };
338
+
339
+ // Test updating existing keys and adding new keys
340
+ " async_map update_and_add" _test = [] {
341
+ glz::async_map<std::string, std::atomic<int >> map;
342
+ map[" alpha" ] = 10 ;
343
+ map[" beta" ] = 20 ;
344
+
345
+ std::string buffer{};
346
+ expect (not glz::write_json (map, buffer));
347
+ expect (buffer == R"( {"alpha":10,"beta":20})" ) << buffer;
348
+
349
+ // Update existing key and add a new key
350
+ map[" alpha" ] = 30 ;
351
+ map[" gamma" ] = 40 ;
352
+
353
+ expect (not glz::write_json (map, buffer));
354
+ expect (buffer == R"( {"alpha":30,"beta":20,"gamma":40})" ) << buffer;
355
+
356
+ // Deserialize and verify
357
+ map.clear ();
358
+ expect (not glz::read_json (map, buffer));
359
+ expect (map.at (" alpha" ).value () == 30 );
360
+ expect (map.at (" beta" ).value () == 20 );
361
+ expect (map.at (" gamma" ).value () == 40 );
362
+ };
363
+
364
+ // Test concurrent access to the async_map
365
+ " async_map concurrent_access" _test = [] {
366
+ glz::async_map<int , std::atomic<int >> map;
367
+ const int num_threads = 10 ;
368
+ const int increments_per_thread = 1000 ;
369
+
370
+ // Initialize map with keys
371
+ for (int i = 0 ; i < num_threads; ++i) {
372
+ map[i] = 0 ;
373
+ }
374
+
375
+ // Launch multiple threads to increment values concurrently
376
+ std::vector<std::thread> threads;
377
+ for (int i = 0 ; i < num_threads; ++i) {
378
+ threads.emplace_back ([&, i]() {
379
+ for (int j = 0 ; j < increments_per_thread; ++j) {
380
+ ++map[i].value ();
381
+ }
382
+ });
383
+ }
384
+
385
+ // Wait for all threads to finish
386
+ for (auto & th : threads) {
387
+ th.join ();
388
+ }
389
+
390
+ // Verify the results
391
+ for (int i = 0 ; i < num_threads; ++i) {
392
+ expect (map.at (i).value () == increments_per_thread) << " Key " << i;
393
+ }
394
+ };
395
+
396
+ // Test removal of keys from the async_map
397
+ " async_map remove_keys" _test = [] {
398
+ glz::async_map<std::string, std::atomic<int >> map;
399
+ map[" first" ] = 100 ;
400
+ map[" second" ] = 200 ;
401
+ map[" third" ] = 300 ;
402
+
403
+ // Remove a key
404
+ map.erase (" second" );
405
+ expect (map.size () == 2 );
406
+ expect (map.find (" second" ) == map.end ());
407
+
408
+ // Serialize and verify
409
+ std::string buffer{};
410
+ expect (not glz::write_json (map, buffer));
411
+ expect (buffer == R"( {"first":100,"third":300})" ) << buffer;
412
+
413
+ // Deserialize and verify
414
+ map.clear ();
415
+ expect (not glz::read_json (map, buffer));
416
+ expect (map.size () == 2 );
417
+ expect (map.at (" first" ).value () == 100 );
418
+ expect (map.at (" third" ).value () == 300 );
419
+ };
420
+
270
421
};
271
422
272
423
int main () { return 0 ; }
0 commit comments