Skip to content

Commit 2ad4c75

Browse files
committed
Merge remote-tracking branch 'origin/main' into philprime/objc-wrapper-sdk-6342
2 parents 45192ca + 9319185 commit 2ad4c75

4 files changed

Lines changed: 550 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### Features
99

10+
- Add Set conformance to SentryAttributeValue (#7876)
1011
- Add SentryObjC wrapper SDK to provide pure Objective-C compatibility layer that wraps the main Sentry SDK with stable, documented Objective-C interfaces. (#7598)
1112
This SDK is designed for projects that require strict Objective-C compatibility without Swift dependencies. It ships as two xcframework variants — `SentryObjC-Static.xcframework.zip` and `SentryObjC-Dynamic.xcframework.zip` — and as a compile-from-source SPM library under the `SentryObjC` product.
1213

Sources/Swift/Protocol/SentryAttributeValue.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ extension Array: SentryAttributeValue {
220220
guard !values.isEmpty, case .string = values[0].asSentryAttributeContent else {
221221
return nil
222222
}
223-
223+
224224
let mappedStringValues = values.compactMap { element -> String? in
225225
guard case .string(let value) = element.asSentryAttributeContent else {
226226
return nil
@@ -231,5 +231,20 @@ extension Array: SentryAttributeValue {
231231
return nil
232232
}
233233
return .stringArray(mappedStringValues)
234-
}
234+
}
235+
}
236+
237+
extension Set: SentryAttributeValue {
238+
/// Converts a set to a `SentryAttributeContent` value.
239+
///
240+
/// Homogeneous sets of `Bool`, `Double`, `Float`, `Int`, and `String` are converted to
241+
/// their corresponding typed array content. For all other element types the set is
242+
/// converted to an `Array` and that extension's homogeneous/heterogeneous logic is
243+
/// applied, ultimately falling back to a string array if the elements are mixed.
244+
///
245+
/// - Note: Sets are unordered, so the resulting array order is not guaranteed to be
246+
/// consistent across calls.
247+
public var asSentryAttributeContent: SentryAttributeContent {
248+
return Array(self).asSentryAttributeContent
249+
}
235250
}

Tests/SentryTests/Protocol/SentryAttributeValuableTests.swift

Lines changed: 175 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,12 +545,12 @@ final class SentryAttributeValueTests: XCTestCase {
545545
return .string("custom")
546546
}
547547
}
548-
548+
549549
let array: [CustomStringType] = []
550-
550+
551551
// -- Act --
552552
let result = array.asSentryAttributeContent
553-
553+
554554
// -- Assert --
555555
// Empty arrays of custom SentryAttributeValue types cannot determine the intended type,
556556
// so they should default to stringArray as a safe fallback
@@ -559,4 +559,176 @@ final class SentryAttributeValueTests: XCTestCase {
559559
}
560560
XCTAssertEqual(value, [])
561561
}
562+
563+
// MARK: - Set Extension Tests
564+
565+
func testAsSentryAttributeContent_whenStringSet_shouldReturnStringArrayCase() {
566+
// -- Arrange --
567+
let set: Set<String> = ["hello", "world", "test"]
568+
569+
// -- Act --
570+
let result = set.asSentryAttributeContent
571+
572+
// -- Assert --
573+
guard case .stringArray(let value) = result else {
574+
return XCTFail("Expected .stringArray case")
575+
}
576+
XCTAssertEqual(Set(value), set)
577+
}
578+
579+
func testAsSentryAttributeContent_whenEmptyStringSet_shouldReturnStringArrayCase() {
580+
// -- Arrange --
581+
let set: Set<String> = []
582+
583+
// -- Act --
584+
let result = set.asSentryAttributeContent
585+
586+
// -- Assert --
587+
guard case .stringArray(let value) = result else {
588+
return XCTFail("Expected .stringArray case")
589+
}
590+
XCTAssertEqual(value, [])
591+
}
592+
593+
func testAsSentryAttributeContent_whenBooleanSet_shouldReturnBooleanArrayCase() {
594+
// -- Arrange --
595+
let set: Set<Bool> = [true, false]
596+
597+
// -- Act --
598+
let result = set.asSentryAttributeContent
599+
600+
// -- Assert --
601+
guard case .booleanArray(let value) = result else {
602+
return XCTFail("Expected .booleanArray case")
603+
}
604+
XCTAssertEqual(Set(value), set)
605+
}
606+
607+
func testAsSentryAttributeContent_whenEmptyBooleanSet_shouldReturnBooleanArrayCase() {
608+
// -- Arrange --
609+
let set: Set<Bool> = []
610+
611+
// -- Act --
612+
let result = set.asSentryAttributeContent
613+
614+
// -- Assert --
615+
guard case .booleanArray(let value) = result else {
616+
return XCTFail("Expected .booleanArray case")
617+
}
618+
XCTAssertEqual(value, [])
619+
}
620+
621+
func testAsSentryAttributeContent_whenIntegerSet_shouldReturnIntegerArrayCase() {
622+
// -- Arrange --
623+
let set: Set<Int> = [1, 2, 3, 42]
624+
625+
// -- Act --
626+
let result = set.asSentryAttributeContent
627+
628+
// -- Assert --
629+
guard case .integerArray(let value) = result else {
630+
return XCTFail("Expected .integerArray case")
631+
}
632+
XCTAssertEqual(Set(value), set)
633+
}
634+
635+
func testAsSentryAttributeContent_whenEmptyIntegerSet_shouldReturnIntegerArrayCase() {
636+
// -- Arrange --
637+
let set: Set<Int> = []
638+
639+
// -- Act --
640+
let result = set.asSentryAttributeContent
641+
642+
// -- Assert --
643+
guard case .integerArray(let value) = result else {
644+
return XCTFail("Expected .integerArray case")
645+
}
646+
XCTAssertEqual(value, [])
647+
}
648+
649+
func testAsSentryAttributeContent_whenDoubleSet_shouldReturnDoubleArrayCase() {
650+
// -- Arrange --
651+
let set: Set<Double> = [1.1, 2.2, 3.14159]
652+
653+
// -- Act --
654+
let result = set.asSentryAttributeContent
655+
656+
// -- Assert --
657+
guard case .doubleArray(let value) = result else {
658+
return XCTFail("Expected .doubleArray case")
659+
}
660+
XCTAssertEqual(Set(value), set)
661+
}
662+
663+
func testAsSentryAttributeContent_whenEmptyDoubleSet_shouldReturnDoubleArrayCase() {
664+
// -- Arrange --
665+
let set: Set<Double> = []
666+
667+
// -- Act --
668+
let result = set.asSentryAttributeContent
669+
670+
// -- Assert --
671+
guard case .doubleArray(let value) = result else {
672+
return XCTFail("Expected .doubleArray case")
673+
}
674+
XCTAssertEqual(value, [])
675+
}
676+
677+
func testAsSentryAttributeContent_whenFloatSet_shouldReturnDoubleArrayCase() {
678+
// -- Arrange --
679+
let set: Set<Float> = [Float(1.1), Float(2.2), Float(3.14159)]
680+
681+
// -- Act --
682+
let result = set.asSentryAttributeContent
683+
684+
// -- Assert --
685+
guard case .doubleArray(let value) = result else {
686+
return XCTFail("Expected .doubleArray case (Float set converted to Double array)")
687+
}
688+
689+
let doubleSet = Set<Double>(set.map { Double($0) })
690+
XCTAssertEqual(Set(value), doubleSet)
691+
}
692+
693+
func testAsSentryAttributeContent_whenEmptyFloatSet_shouldReturnDoubleArrayCase() {
694+
// -- Arrange --
695+
let set: Set<Float> = []
696+
697+
// -- Act --
698+
let result = set.asSentryAttributeContent
699+
700+
// -- Assert --
701+
guard case .doubleArray(let value) = result else {
702+
return XCTFail("Expected .doubleArray case (Float set converted to Double array)")
703+
}
704+
XCTAssertEqual(value, [])
705+
}
706+
707+
func testAsSentryAttributeContent_whenSingleElementStringSet_shouldReturnStringArrayCase() {
708+
// -- Arrange --
709+
let set: Set<String> = ["single"]
710+
711+
// -- Act --
712+
let result = set.asSentryAttributeContent
713+
714+
// -- Assert --
715+
guard case .stringArray(let value) = result else {
716+
return XCTFail("Expected .stringArray case")
717+
}
718+
XCTAssertEqual(value, ["single"])
719+
}
720+
721+
func testAsSentryAttributeContent_whenHeterogeneousAnyHashableSet_shouldReturnStringArrayCase() {
722+
// -- Arrange --
723+
let set: Set<AnyHashable> = ["hello", 42]
724+
725+
// -- Act --
726+
let result = set.asSentryAttributeContent
727+
728+
// -- Assert --
729+
guard case .stringArray(let value) = result else {
730+
return XCTFail("Expected .stringArray case for heterogeneous AnyHashable set")
731+
}
732+
XCTAssertEqual(value.sorted(), ["42", "hello"])
733+
}
562734
}

0 commit comments

Comments
 (0)