Skip to content

Commit 903425b

Browse files
committed
add join()
1 parent b377edb commit 903425b

File tree

4 files changed

+44
-2
lines changed

4 files changed

+44
-2
lines changed

Firestore/Swift/Source/ExpressionImplementation.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ public extension Expression {
609609

610610
// --- Added String Operations ---
611611

612+
func join(delimiter: String) -> FunctionExpression {
613+
return FunctionExpression("join", [self, Constant(delimiter)])
614+
}
615+
612616
func length() -> FunctionExpression {
613617
return FunctionExpression("length", [self])
614618
}

Firestore/Swift/Source/SwiftAPI/Pipeline/Expressions/Expression.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,19 @@ public protocol Expression: Sendable {
706706

707707
// MARK: String Operations
708708

709+
/// Creates an expression that joins the elements of an array of strings with a given separator.
710+
///
711+
/// Assumes `self` evaluates to an array of strings.
712+
///
713+
/// ```swift
714+
/// // Join the "tags" array with a ", " separator.
715+
/// Field("tags").join(separator: ", ")
716+
/// ```
717+
///
718+
/// - Parameter delimiter: The string to use as a delimiter.
719+
/// - Returns: A new `FunctionExpression` representing the joined string.
720+
func join(delimiter: String) -> FunctionExpression
721+
709722
/// Creates an expression that returns the length of a string.
710723
///
711724
/// ```swift

Firestore/Swift/Tests/Integration/PipelineTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,31 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
28782878
TestHelper.compare(snapshot: snapshot, expected: expectedResults, enforceOrder: true)
28792879
}
28802880

2881+
func testJoinWorks() async throws {
2882+
let collRef = collectionRef(withDocuments: [
2883+
"doc1": ["tags": ["a", "b", "c"]],
2884+
"doc2": ["tags": ["d", "e"]],
2885+
"doc3": ["tags": []],
2886+
])
2887+
let db = collRef.firestore
2888+
2889+
let pipeline = db.pipeline()
2890+
.collection(collRef.path)
2891+
.select([
2892+
Field("tags").join(delimiter: ", ").as("tagsString"),
2893+
])
2894+
2895+
let snapshot = try await pipeline.execute()
2896+
2897+
let expectedResults: [[String: Sendable]] = [
2898+
["tagsString": "a, b, c"],
2899+
["tagsString": "d, e"],
2900+
["tagsString": ""],
2901+
]
2902+
2903+
TestHelper.compare(snapshot: snapshot, expected: expectedResults, enforceOrder: false)
2904+
}
2905+
28812906
func testSupportsRand() async throws {
28822907
let collRef = collectionRef(withDocuments: bookDocs)
28832908
let db = collRef.firestore

Firestore/Swift/Tests/TestHelper/TestHelper.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public enum TestHelper {
161161

162162
for (key, value1) in dict1 {
163163
guard let value2 = dict2[key], areEqual(value1, value2) else {
164-
XCTFail("""
164+
print("""
165165
Dictionary value mismatch for key: '\(key)'
166166
Actual value: '\(String(describing: value1))' (from dict1)
167167
Expected value: '\(String(describing: dict2[key]))' (from dict2)
@@ -180,7 +180,7 @@ public enum TestHelper {
180180
for (index, value1) in array1.enumerated() {
181181
let value2 = array2[index]
182182
if !areEqual(value1, value2) {
183-
XCTFail("""
183+
print("""
184184
Array value mismatch.
185185
Actual array value: '\(String(describing: value1))'
186186
Expected array value: '\(String(describing: value2))'

0 commit comments

Comments
 (0)