Skip to content

Commit b4d5e8b

Browse files
committed
more tests
1 parent d6dfc51 commit b4d5e8b

File tree

2 files changed

+222
-0
lines changed

2 files changed

+222
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
public class RandomExpr: FunctionExpr, @unchecked Sendable {
16+
public init() {
17+
super.init("rand", [])
18+
}
19+
}

Firestore/Swift/Tests/Integration/PipelineTests.swift

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,4 +2347,207 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
23472347

23482348
TestHelper.compare(pipelineSnapshot: snapshot, expected: expectedResults, enforceOrder: true)
23492349
}
2350+
2351+
func testSupportsRand() async throws {
2352+
let collRef = collectionRef(withDocuments: bookDocs)
2353+
let db = collRef.firestore
2354+
2355+
let pipeline = db.pipeline()
2356+
.collection(collRef.path)
2357+
.limit(10)
2358+
.select(RandomExpr().as("result"))
2359+
2360+
let snapshot = try await pipeline.execute()
2361+
2362+
XCTAssertEqual(snapshot.results.count, 10, "Should fetch 10 documents")
2363+
2364+
for doc in snapshot.results {
2365+
guard let resultValue = doc.get("result") else {
2366+
XCTFail("Document \(doc.id ?? "unknown") should have a 'result' field")
2367+
continue
2368+
}
2369+
guard let doubleValue = resultValue as? Double else {
2370+
XCTFail("Result value for document \(doc.id ?? "unknown") is not a Double: \(resultValue)")
2371+
continue
2372+
}
2373+
XCTAssertGreaterThanOrEqual(
2374+
doubleValue,
2375+
0.0,
2376+
"Result for \(doc.id ?? "unknown") should be >= 0.0"
2377+
)
2378+
XCTAssertLessThan(doubleValue, 1.0, "Result for \(doc.id ?? "unknown") should be < 1.0")
2379+
}
2380+
}
2381+
2382+
func testSupportsArray() async throws {
2383+
let db = firestore()
2384+
let collRef = collectionRef(withDocuments: bookDocs)
2385+
2386+
let pipeline = db.pipeline()
2387+
.collection(collRef.path)
2388+
.sort(Field("rating").descending())
2389+
.limit(1)
2390+
.select(ArrayExpression([1, 2, 3, 4]).as("metadata"))
2391+
2392+
let snapshot = try await pipeline.execute()
2393+
2394+
XCTAssertEqual(snapshot.results.count, 1, "Should retrieve one document")
2395+
2396+
let expectedResults: [String: Sendable?] = ["metadata": [1, 2, 3, 4]]
2397+
2398+
if let resultDoc = snapshot.results.first {
2399+
TestHelper.compare(pipelineResult: resultDoc, expected: expectedResults)
2400+
} else {
2401+
XCTFail("No document retrieved for testSupportsArray")
2402+
}
2403+
}
2404+
2405+
func testEvaluatesExpressionInArray() async throws {
2406+
let db = firestore()
2407+
let collRef = collectionRef(withDocuments: bookDocs)
2408+
2409+
let pipeline = db.pipeline()
2410+
.collection(collRef.path)
2411+
.sort(Field("rating").descending())
2412+
.limit(1)
2413+
.select(ArrayExpression([
2414+
1,
2415+
2,
2416+
Field("genre"),
2417+
Field("rating").multiply(10),
2418+
]).as("metadata"))
2419+
2420+
let snapshot = try await pipeline.execute()
2421+
2422+
XCTAssertEqual(snapshot.results.count, 1, "Should retrieve one document")
2423+
2424+
let expectedResults: [String: Sendable?] = ["metadata": [1, 2, "Fantasy", 47.0]]
2425+
2426+
if let resultDoc = snapshot.results.first {
2427+
TestHelper.compare(pipelineResult: resultDoc, expected: expectedResults)
2428+
} else {
2429+
XCTFail("No document retrieved for testEvaluatesExpressionInArray")
2430+
}
2431+
}
2432+
2433+
func testSupportsArrayOffset() async throws {
2434+
let db = firestore()
2435+
let collRef = collectionRef(withDocuments: bookDocs)
2436+
2437+
let expectedResultsPart1: [[String: Sendable?]] = [
2438+
["firstTag": "adventure"], // book4 (rating 4.7)
2439+
["firstTag": "politics"], // book10 (rating 4.6)
2440+
["firstTag": "classic"], // book2 (rating 4.5)
2441+
]
2442+
2443+
// Part 1: Using arrayOffset as FunctionExpr("array_offset", ...)
2444+
// (Assuming direct top-level ArrayOffset() isn't available, as per Expr.swift structure)
2445+
let pipeline1 = db.pipeline()
2446+
.collection(collRef.path)
2447+
.sort(Field("rating").descending())
2448+
.limit(3)
2449+
.select(Field("tags").arrayOffset(0).as("firstTag"))
2450+
2451+
let snapshot1 = try await pipeline1.execute()
2452+
XCTAssertEqual(snapshot1.results.count, 3, "Part 1: Should retrieve three documents")
2453+
TestHelper.compare(
2454+
pipelineSnapshot: snapshot1,
2455+
expected: expectedResultsPart1,
2456+
enforceOrder: true
2457+
)
2458+
}
2459+
2460+
func testSupportsMap() async throws {
2461+
let db = firestore()
2462+
let collRef = collectionRef(withDocuments: bookDocs)
2463+
2464+
let pipeline = db.pipeline()
2465+
.collection(collRef.path)
2466+
.sort(Field("rating").descending())
2467+
.limit(1)
2468+
.select(MapExpression(["foo": "bar"]).as("metadata"))
2469+
2470+
let snapshot = try await pipeline.execute()
2471+
2472+
XCTAssertEqual(snapshot.results.count, 1, "Should retrieve one document")
2473+
2474+
let expectedResult: [String: Sendable?] = ["metadata": ["foo": "bar"]]
2475+
2476+
if let resultDoc = snapshot.results.first {
2477+
TestHelper.compare(pipelineResult: resultDoc, expected: expectedResult)
2478+
} else {
2479+
XCTFail("No document retrieved for testSupportsMap")
2480+
}
2481+
}
2482+
2483+
func testEvaluatesExpressionInMap() async throws {
2484+
let db = firestore()
2485+
let collRef = collectionRef(withDocuments: bookDocs)
2486+
2487+
let pipeline = db.pipeline()
2488+
.collection(collRef.path)
2489+
.sort(Field("rating").descending())
2490+
.limit(1)
2491+
.select(MapExpression([
2492+
"genre": Field("genre"), // "Fantasy"
2493+
"rating": Field("rating").multiply(10), // 4.7 * 10 = 47.0
2494+
]).as("metadata"))
2495+
2496+
let snapshot = try await pipeline.execute()
2497+
2498+
XCTAssertEqual(snapshot.results.count, 1, "Should retrieve one document")
2499+
2500+
// Expected: genre is "Fantasy", rating is 4.7 for book4
2501+
let expectedResult: [String: Sendable?] = ["metadata": ["genre": "Fantasy", "rating": 47.0]]
2502+
2503+
if let resultDoc = snapshot.results.first {
2504+
TestHelper.compare(pipelineResult: resultDoc, expected: expectedResult)
2505+
} else {
2506+
XCTFail("No document retrieved for testEvaluatesExpressionInMap")
2507+
}
2508+
}
2509+
2510+
func testSupportsMapRemove() async throws {
2511+
let db = firestore()
2512+
let collRef = collectionRef(withDocuments: bookDocs)
2513+
2514+
let expectedResult: [String: Sendable?] = ["awards": ["nebula": false]]
2515+
2516+
let pipeline2 = db.pipeline()
2517+
.collection(collRef.path)
2518+
.sort(Field("rating").descending())
2519+
.limit(1)
2520+
.select(Field("awards").mapRemove("hugo").as("awards"))
2521+
2522+
let snapshot2 = try await pipeline2.execute()
2523+
XCTAssertEqual(snapshot2.results.count, 1, "Should retrieve one document")
2524+
if let resultDoc2 = snapshot2.results.first {
2525+
TestHelper.compare(pipelineResult: resultDoc2, expected: expectedResult)
2526+
} else {
2527+
XCTFail("No document retrieved for testSupportsMapRemove")
2528+
}
2529+
}
2530+
2531+
func testSupportsMapMerge() async throws {
2532+
let db = firestore()
2533+
let collRef = collectionRef(withDocuments: bookDocs)
2534+
2535+
let expectedResult: [String: Sendable?] =
2536+
["awards": ["hugo": false, "nebula": false, "fakeAward": true]]
2537+
let mergeMap: [String: Sendable] = ["fakeAward": true]
2538+
2539+
let pipeline = db.pipeline()
2540+
.collection(collRef.path)
2541+
.sort(Field("rating").descending())
2542+
.limit(1)
2543+
.select(Field("awards").mapMerge(mergeMap).as("awards"))
2544+
2545+
let snapshot = try await pipeline.execute()
2546+
XCTAssertEqual(snapshot.results.count, 1, "Should retrieve one document")
2547+
if let resultDoc = snapshot.results.first {
2548+
TestHelper.compare(pipelineResult: resultDoc, expected: expectedResult)
2549+
} else {
2550+
XCTFail("No document retrieved for testSupportsMapMerge")
2551+
}
2552+
}
23502553
}

0 commit comments

Comments
 (0)