@@ -1186,4 +1186,167 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
1186
1186
)
1187
1187
expectSnapshots ( snapshot: snapshot, expected: expectedResults)
1188
1188
}
1189
+
1190
+ func testSortOffsetAndLimitStages( ) async throws {
1191
+ let collRef = collectionRef ( withDocuments: bookDocs)
1192
+ let db = collRef. firestore
1193
+
1194
+ let pipeline = db. pipeline ( )
1195
+ . collection ( collRef. path)
1196
+ . sort ( Field ( " author " ) . ascending ( ) )
1197
+ . offset ( 5 )
1198
+ . limit ( 3 )
1199
+ . select ( " title " , " author " )
1200
+
1201
+ let snapshot = try await pipeline. execute ( )
1202
+
1203
+ let expectedResults : [ [ String : Sendable ] ] = [
1204
+ [ " title " : " 1984 " , " author " : " George Orwell " ] ,
1205
+ [ " title " : " To Kill a Mockingbird " , " author " : " Harper Lee " ] ,
1206
+ [ " title " : " The Lord of the Rings " , " author " : " J.R.R. Tolkien " ] ,
1207
+ ]
1208
+ expectSnapshots ( snapshot: snapshot, expected: expectedResults)
1209
+ }
1210
+
1211
+ // MARK: - Generic Stage Tests
1212
+
1213
+ func testRawStageSelectFields( ) async throws {
1214
+ let collRef = collectionRef ( withDocuments: bookDocs)
1215
+ let db = collRef. firestore
1216
+
1217
+ // Expected book: book2 (Pride and Prejudice, Jane Austen, 1813)
1218
+ // It's the earliest published book.
1219
+ let expectedSelectedData : [ String : Sendable ] = [
1220
+ " title " : " Pride and Prejudice " ,
1221
+ // "metadata": ["author": "Douglas Adams"]
1222
+ ]
1223
+
1224
+ // The parameters for rawStage("select", ...) are an array containing a single dictionary.
1225
+ // The keys of this dictionary are the output field names, and the values are Field objects.
1226
+ let selectParameters : [ [ String : Sendable ] ] =
1227
+ [
1228
+ // Field("title").as("title")
1229
+ [ " title " : Field ( " author " ) ] ,
1230
+ ]
1231
+
1232
+ let pipeline = db. pipeline ( )
1233
+ . collection ( collRef. path)
1234
+ . sort ( Field ( " published " ) . ascending ( ) )
1235
+ . limit ( 1 )
1236
+ . rawStage ( name: " select " , params: selectParameters) // Using rawStage for selection
1237
+
1238
+ let snapshot = try await pipeline. execute ( )
1239
+
1240
+ XCTAssertEqual ( snapshot. results. count, 1 , " Should retrieve one document " )
1241
+ expectSnapshots ( snapshot: snapshot, expected: [ expectedSelectedData] )
1242
+ }
1243
+
1244
+ // TODO:
1245
+
1246
+ // MARK: - Replace Stage Test
1247
+
1248
+ func testReplaceStagePromoteAwardsAndAddFlag( ) async throws {
1249
+ let collRef = collectionRef ( withDocuments: bookDocs)
1250
+ let db = collRef. firestore
1251
+
1252
+ let pipeline = db. pipeline ( )
1253
+ . collection ( collRef. path)
1254
+ . where ( Field ( " title " ) . eq ( " The Hitchhiker's Guide to the Galaxy " ) )
1255
+ . replace ( with: " awards " )
1256
+
1257
+ let snapshot = try await pipeline. execute ( )
1258
+
1259
+ expectResults ( snapshot, expectedCount: 1 )
1260
+
1261
+ let expectedBook1Transformed : [ String : Sendable ? ] = [
1262
+ " hugo " : true ,
1263
+ " nebula " : false ,
1264
+ " others " : [ " unknown " : [ " year " : 1980 ] ] ,
1265
+ ]
1266
+
1267
+ // Need to use nullable Sendable for comparison because 'others' is nested
1268
+ // and the areEqual function handles Sendable?
1269
+ expectSnapshots ( snapshot: snapshot, expected: [ expectedBook1Transformed as [ String : Sendable ] ] )
1270
+ }
1271
+
1272
+ // MARK: - Sample Stage Tests
1273
+
1274
+ func testSampleStageLimit3( ) async throws {
1275
+ let collRef = collectionRef ( withDocuments: bookDocs)
1276
+ let db = collRef. firestore
1277
+
1278
+ let pipeline = db. pipeline ( )
1279
+ . collection ( collRef. path)
1280
+ . sort ( DocumentId ( ) . ascending ( ) ) // Sort for predictable results
1281
+ . limit ( 3 ) // Simulate sampling 3 documents
1282
+
1283
+ let snapshot = try await pipeline. execute ( )
1284
+
1285
+ expectResults ( snapshot, expectedCount: 3 )
1286
+
1287
+ // Based on documentID ascending sort of bookDocs keys:
1288
+ // book1, book10, book2, book3, ...
1289
+ let expectedIDs = [ " book1 " , " book10 " , " book2 " ]
1290
+ expectResults ( snapshot, expectedIDs: expectedIDs)
1291
+ }
1292
+
1293
+ func testSampleStageLimitDocuments3( ) async throws {
1294
+ let collRef = collectionRef ( withDocuments: bookDocs)
1295
+ let db = collRef. firestore
1296
+
1297
+ let pipeline = db. pipeline ( )
1298
+ . collection ( collRef. path)
1299
+ . sort ( DocumentId ( ) . ascending ( ) ) // Sort for predictable results
1300
+ . limit ( 3 ) // Simulate sampling {documents: 3}
1301
+
1302
+ let snapshot = try await pipeline. execute ( )
1303
+
1304
+ expectResults ( snapshot, expectedCount: 3 )
1305
+
1306
+ // Based on documentID ascending sort of bookDocs keys:
1307
+ // book1, book10, book2, book3, ...
1308
+ let expectedIDs = [ " book1 " , " book10 " , " book2 " ]
1309
+ expectResults ( snapshot, expectedIDs: expectedIDs)
1310
+ }
1311
+
1312
+ func testSampleStageLimitPercentage60( ) async throws {
1313
+ let collRef = collectionRef ( withDocuments: bookDocs)
1314
+ let db = collRef. firestore
1315
+
1316
+ let totalDocs = bookDocs. count
1317
+ let percentage = 0.6
1318
+ let limitCount = Int ( Double ( totalDocs) * percentage) // 10 * 0.6 = 6
1319
+
1320
+ let pipeline = db. pipeline ( )
1321
+ . collection ( collRef. path)
1322
+ . sort ( DocumentId ( ) . ascending ( ) ) // Sort for predictable results
1323
+ . limit ( Int32 ( limitCount) ) // Simulate sampling {percentage: 0.6}
1324
+
1325
+ let snapshot = try await pipeline. execute ( )
1326
+
1327
+ expectResults ( snapshot, expectedCount: limitCount) // Should be 6
1328
+
1329
+ // Based on documentID ascending sort of bookDocs keys:
1330
+ // book1, book10, book2, book3, book4, book5, book6, book7, book8, book9
1331
+ let expectedIDs = [ " book1 " , " book10 " , " book2 " , " book3 " , " book4 " , " book5 " ]
1332
+ expectResults ( snapshot, expectedIDs: expectedIDs)
1333
+ }
1334
+
1335
+ // MARK: - Union Stage Test
1336
+
1337
+ func testUnionStageCombineAuthors( ) async throws {
1338
+ let collRef = collectionRef ( withDocuments: bookDocs)
1339
+ let db = collRef. firestore
1340
+
1341
+ let pipeline = db. pipeline ( )
1342
+ . collection ( collRef. path)
1343
+ . union ( db. pipeline ( )
1344
+ . collection ( collRef. path) )
1345
+
1346
+ let snapshot = try await pipeline. execute ( )
1347
+
1348
+ let bookSequence = ( 1 ... 10 ) . map { " book \( $0) " }
1349
+ let repeatedIDs = bookSequence + bookSequence
1350
+ expectResults ( snapshot, expectedIDs: repeatedIDs)
1351
+ }
1189
1352
}
0 commit comments