@@ -357,6 +357,59 @@ class LoggingTest: XCTestCase {
357357 " nested-list " : [ " l1str " , [ " l2str1 " , " l2str2 " ] ] ] )
358358 }
359359
360+ func testMergeMetadataExistingMetadata( ) {
361+ let testLogging = TestLogging ( )
362+ LoggingSystem . bootstrapInternal { testLogging. make ( label: $0) }
363+
364+ var logger = Logger ( label: " \( #function) " )
365+ let metadata : Logger . Metadata = [
366+ " foo " : [ " bar " , " buz " ] ,
367+ " empty-list " : [ ] ,
368+ " nested-list " : [ " l1str " , [ " l2str1 " , " l2str2 " ] ] ,
369+ ]
370+ logger. mergeMetadata ( metadata)
371+ logger. info ( " first log " )
372+ testLogging. history. assertExist ( level: . info,
373+ message: " first log " ,
374+ metadata: [ " foo " : [ " bar " , " buz " ] ,
375+ " empty-list " : [ ] ,
376+ " nested-list " : [ " l1str " , [ " l2str1 " , " l2str2 " ] ] ] )
377+
378+ // Non-overlapping metadata key-value pairs should be added without affecting existing metadata,
379+ // while overlapping metadata key-value pairs should update the existing key's value.
380+ logger. mergeMetadata ( [
381+ " foo " : [ " bar " ] , // drops "buz" for existing key value
382+ " newkey " : " newvalue1 " // adds new key-value pair
383+ ] )
384+ logger. info ( " second log " )
385+ testLogging. history. assertExist ( level: . info,
386+ message: " second log " ,
387+ metadata: [ " foo " : [ " bar " ] ,
388+ " empty-list " : [ ] ,
389+ " nested-list " : [ " l1str " , [ " l2str1 " , " l2str2 " ] ] ,
390+ " newkey " : " newvalue1 " ] )
391+
392+ // Finally, if new metadata with overlapping keys is added more than once, the
393+ // latest value should be the one set in the Logger metadata.
394+ logger. mergeMetadata ( [
395+ " foo " : [ ] ,
396+ " newkey " : " newvalue2 "
397+ ] )
398+ logger. mergeMetadata ( [
399+ " foo " : " a new type for this value " ,
400+ " newkey " : " newvalue3 "
401+ ] )
402+ logger. info ( " second log " )
403+ testLogging. history. assertExist ( level: . info,
404+ message: " second log " ,
405+ metadata: [ " foo " : " a new type for this value " ,
406+ " empty-list " : [ ] ,
407+ " nested-list " : [ " l1str " , [ " l2str1 " , " l2str2 " ] ] ,
408+ " newkey " : " newvalue3 " ] )
409+
410+
411+ }
412+
360413 // Example of custom "box" which may be used to implement "render at most once" semantics
361414 // Not thread-safe, thus should not be shared across threads.
362415 internal final class LazyMetadataBox : CustomStringConvertible {
0 commit comments