@@ -367,4 +367,167 @@ struct ObjectsPoolTests {
367367 #expect( pool. entries [ " map:toremove@1 " ] == nil )
368368 }
369369 }
370+
371+ /// Tests for the `getOrCreateCounter` and `getOrCreateMap` methods
372+ struct GetOrCreateTests {
373+ @Test
374+ func getOrCreateCounter_returnsExistingCounter( ) {
375+ let logger = TestLogger ( )
376+ let userCallbackQueue = DispatchQueue . main
377+ let clock = MockSimpleClock ( )
378+
379+ // Create a counter in the pool first
380+ let existingCounter = InternalDefaultLiveCounter . createZeroValued (
381+ objectID: " counter:test@123 " ,
382+ logger: logger,
383+ userCallbackQueue: userCallbackQueue,
384+ clock: clock,
385+ )
386+ var pool = ObjectsPool (
387+ logger: logger,
388+ userCallbackQueue: userCallbackQueue,
389+ clock: clock,
390+ testsOnly_otherEntries: [ " counter:test@123 " : . counter( existingCounter) ] ,
391+ )
392+
393+ // Create a creation operation with the same object ID as the existing counter
394+ let creationOperation = ObjectCreationHelpers . ObjectCreationOperation (
395+ objectID: " counter:test@123 " ,
396+ operation: ObjectOperation (
397+ action: . known( . counterCreate) ,
398+ objectId: " counter:test@123 " ,
399+ counter: WireObjectsCounter ( count: NSNumber ( value: 42.0 ) ) ,
400+ nonce: " testnonce " ,
401+ initialValue: " { \" action \" :3, \" counter \" :{ \" count \" :42}} " ,
402+ ) ,
403+ objectMessage: OutboundObjectMessage (
404+ operation: ObjectOperation (
405+ action: . known( . counterCreate) ,
406+ objectId: " counter:test@123 " ,
407+ counter: WireObjectsCounter ( count: NSNumber ( value: 42.0 ) ) ,
408+ nonce: " testnonce " ,
409+ initialValue: " { \" action \" :3, \" counter \" :{ \" count \" :42}} " ,
410+ ) ,
411+ ) ,
412+ )
413+
414+ // Should return the existing counter
415+ let result = pool. getOrCreateCounter (
416+ creationOperation: creationOperation,
417+ logger: logger,
418+ userCallbackQueue: userCallbackQueue,
419+ clock: clock,
420+ )
421+
422+ #expect( result === existingCounter)
423+ }
424+
425+ @Test
426+ func getOrCreateCounter_createsNewCounterWhenNotExists( ) {
427+ let logger = TestLogger ( )
428+ let userCallbackQueue = DispatchQueue . main
429+ let clock = MockSimpleClock ( )
430+ var pool = ObjectsPool ( logger: logger, userCallbackQueue: userCallbackQueue, clock: clock)
431+
432+ // Create a creation operation
433+ let creationOperation = ObjectCreationHelpers . creationOperationForLiveCounter (
434+ count: 42.0 ,
435+ timestamp: Date ( ) ,
436+ )
437+
438+ // Should create a new counter
439+ let result = pool. getOrCreateCounter (
440+ creationOperation: creationOperation,
441+ logger: logger,
442+ userCallbackQueue: userCallbackQueue,
443+ clock: clock,
444+ )
445+
446+ #expect( result. objectID == creationOperation. objectID)
447+ #expect( pool. entries [ creationOperation. objectID] ? . counterValue === result)
448+ }
449+
450+ @Test
451+ func getOrCreateMap_returnsExistingMap( ) {
452+ let logger = TestLogger ( )
453+ let userCallbackQueue = DispatchQueue . main
454+ let clock = MockSimpleClock ( )
455+
456+ // Create a map in the pool first
457+ let existingMap = InternalDefaultLiveMap . createZeroValued (
458+ objectID: " map:test@123 " ,
459+ logger: logger,
460+ userCallbackQueue: userCallbackQueue,
461+ clock: clock,
462+ )
463+ var pool = ObjectsPool (
464+ logger: logger,
465+ userCallbackQueue: userCallbackQueue,
466+ clock: clock,
467+ testsOnly_otherEntries: [ " map:test@123 " : . map( existingMap) ] ,
468+ )
469+
470+ // Create a creation operation with the same object ID as the existing map
471+ let creationOperation = ObjectCreationHelpers . ObjectCreationOperation (
472+ objectID: " map:test@123 " ,
473+ operation: ObjectOperation (
474+ action: . known( . mapCreate) ,
475+ objectId: " map:test@123 " ,
476+ map: ObjectsMap (
477+ semantics: . known( . lww) ,
478+ entries: [ : ] ,
479+ ) ,
480+ nonce: " testnonce " ,
481+ initialValue: " { \" action \" :0, \" map \" :{ \" semantics \" :0, \" entries \" :{}}} " ,
482+ ) ,
483+ objectMessage: OutboundObjectMessage (
484+ operation: ObjectOperation (
485+ action: . known( . mapCreate) ,
486+ objectId: " map:test@123 " ,
487+ map: ObjectsMap (
488+ semantics: . known( . lww) ,
489+ entries: [ : ] ,
490+ ) ,
491+ nonce: " testnonce " ,
492+ initialValue: " { \" action \" :0, \" map \" :{ \" semantics \" :0, \" entries \" :{}}} " ,
493+ ) ,
494+ ) ,
495+ )
496+
497+ // Should return the existing map
498+ let result = pool. getOrCreateMap (
499+ creationOperation: creationOperation,
500+ logger: logger,
501+ userCallbackQueue: userCallbackQueue,
502+ clock: clock,
503+ )
504+
505+ #expect( result === existingMap)
506+ }
507+
508+ @Test
509+ func getOrCreateMap_createsNewMapWhenNotExists( ) {
510+ let logger = TestLogger ( )
511+ let userCallbackQueue = DispatchQueue . main
512+ let clock = MockSimpleClock ( )
513+ var pool = ObjectsPool ( logger: logger, userCallbackQueue: userCallbackQueue, clock: clock)
514+
515+ // Create a creation operation
516+ let creationOperation = ObjectCreationHelpers . creationOperationForLiveMap (
517+ entries: [ : ] ,
518+ timestamp: Date ( ) ,
519+ )
520+
521+ // Should create a new map
522+ let result = pool. getOrCreateMap (
523+ creationOperation: creationOperation,
524+ logger: logger,
525+ userCallbackQueue: userCallbackQueue,
526+ clock: clock,
527+ )
528+
529+ #expect( result. objectID == creationOperation. objectID)
530+ #expect( pool. entries [ creationOperation. objectID] ? . mapValue === result)
531+ }
532+ }
370533}
0 commit comments