Skip to content

Commit 54461f1

Browse files
committed
add floor()
1 parent 814074f commit 54461f1

File tree

3 files changed

+141
-101
lines changed

3 files changed

+141
-101
lines changed

Firestore/Swift/Source/ExpressionImplementation.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ public extension Expression {
242242
return FunctionExpression("ceil", [self])
243243
}
244244

245+
func floor() -> FunctionExpression {
246+
return FunctionExpression("floor", [self])
247+
}
248+
245249
func exp() -> FunctionExpression {
246250
return FunctionExpression("exp", [self])
247251
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ public protocol Expression: Sendable {
3636

3737
// --- Added Mathematical Operations ---
3838

39+
/// Creates an expression that returns the largest numeric value that isn't greater than X.
40+
///
41+
/// ```swift
42+
/// // Get the floor of the "amount" field.
43+
/// Field("amount").floor()
44+
/// ```
45+
///
46+
/// - Returns: A new `FunctionExpression` representing the floor of the number.
47+
func floor() -> FunctionExpression
48+
3949
/// Creates an expression that returns e to the power of X.
4050
///
4151
/// Returns zero on underflow and nil on overflow.

Firestore/Swift/Tests/Integration/PipelineTests.swift

Lines changed: 127 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,32 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
20522052
TestHelper.compare(pipelineSnapshot: snapshot, expected: expectedResults, enforceOrder: true)
20532053
}
20542054

2055+
func testFloorWorks() async throws {
2056+
let collRef = collectionRef(withDocuments: [
2057+
"doc1": ["value": -10.8],
2058+
"doc2": ["value": 5.3],
2059+
"doc3": ["value": 0],
2060+
])
2061+
let db = collRef.firestore
2062+
2063+
let pipeline = db.pipeline()
2064+
.collection(collRef.path)
2065+
.select([
2066+
Field("value").floor().as("floorValue"),
2067+
])
2068+
.sort([Field("floorValue").ascending()])
2069+
2070+
let snapshot = try await pipeline.execute()
2071+
2072+
let expectedResults: [[String: Sendable]] = [
2073+
["floorValue": -11],
2074+
["floorValue": 0],
2075+
["floorValue": 5],
2076+
]
2077+
2078+
TestHelper.compare(pipelineSnapshot: snapshot, expected: expectedResults, enforceOrder: true)
2079+
}
2080+
20552081
func testExpWorks() async throws {
20562082
let collRef = collectionRef(withDocuments: [
20572083
"doc1": ["value": 1],
@@ -2992,107 +3018,107 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
29923018
)
29933019
}
29943020

2995-
func testBitAnd() async throws {
2996-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
2997-
let db = firestore()
2998-
let randomCol = collectionRef()
2999-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3000-
3001-
let pipeline = db.pipeline()
3002-
.collection(randomCol.path)
3003-
.limit(1)
3004-
.select([Constant(5).bitAnd(12).as("result")])
3005-
let snapshot = try await pipeline.execute()
3006-
TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 4]], enforceOrder: false)
3007-
}
3008-
3009-
func testBitOr() async throws {
3010-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3011-
let db = firestore()
3012-
let randomCol = collectionRef()
3013-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3014-
3015-
let pipeline = db.pipeline()
3016-
.collection(randomCol.path)
3017-
.limit(1)
3018-
.select([Constant(5).bitOr(12).as("result")])
3019-
let snapshot = try await pipeline.execute()
3020-
TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 13]], enforceOrder: false)
3021-
}
3022-
3023-
func testBitXor() async throws {
3024-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3025-
let db = firestore()
3026-
let randomCol = collectionRef()
3027-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3028-
3029-
let pipeline = db.pipeline()
3030-
.collection(randomCol.path)
3031-
.limit(1)
3032-
.select([Constant(5).bitXor(12).as("result")])
3033-
let snapshot = try await pipeline.execute()
3034-
TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 9]], enforceOrder: false)
3035-
}
3036-
3037-
func testBitNot() async throws {
3038-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3039-
let db = firestore()
3040-
let randomCol = collectionRef()
3041-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3042-
let bytesInput = Data([0xFD])
3043-
let expectedOutput = Data([0x02])
3044-
3045-
let pipeline = db.pipeline()
3046-
.collection(randomCol.path)
3047-
.limit(1)
3048-
.select([Constant(bytesInput).bitNot().as("result")])
3049-
let snapshot = try await pipeline.execute()
3050-
TestHelper.compare(
3051-
pipelineSnapshot: snapshot,
3052-
expected: [["result": expectedOutput]],
3053-
enforceOrder: false
3054-
)
3055-
}
3056-
3057-
func testBitLeftShift() async throws {
3058-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3059-
let db = firestore()
3060-
let randomCol = collectionRef()
3061-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3062-
let bytesInput = Data([0x02])
3063-
let expectedOutput = Data([0x08])
3064-
3065-
let pipeline = db.pipeline()
3066-
.collection(randomCol.path)
3067-
.limit(1)
3068-
.select([Constant(bytesInput).bitLeftShift(2).as("result")])
3069-
let snapshot = try await pipeline.execute()
3070-
TestHelper.compare(
3071-
pipelineSnapshot: snapshot,
3072-
expected: [["result": expectedOutput]],
3073-
enforceOrder: false
3074-
)
3075-
}
3076-
3077-
func testBitRightShift() async throws {
3078-
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3079-
let db = firestore()
3080-
let randomCol = collectionRef()
3081-
try await randomCol.document("dummyDoc").setData(["field": "value"])
3082-
let bytesInput = Data([0x02])
3083-
let expectedOutput = Data([0x00])
3084-
3085-
let pipeline = db.pipeline()
3086-
.collection(randomCol.path)
3087-
.limit(1)
3088-
.select([Constant(bytesInput).bitRightShift(2).as("result")])
3089-
let snapshot = try await pipeline.execute()
3090-
TestHelper.compare(
3091-
pipelineSnapshot: snapshot,
3092-
expected: [["result": expectedOutput]],
3093-
enforceOrder: false
3094-
)
3095-
}
3021+
// func testBitAnd() async throws {
3022+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3023+
// let db = firestore()
3024+
// let randomCol = collectionRef()
3025+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3026+
//
3027+
// let pipeline = db.pipeline()
3028+
// .collection(randomCol.path)
3029+
// .limit(1)
3030+
// .select([Constant(5).bitAnd(12).as("result")])
3031+
// let snapshot = try await pipeline.execute()
3032+
// TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 4]], enforceOrder: false)
3033+
// }
3034+
//
3035+
// func testBitOr() async throws {
3036+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3037+
// let db = firestore()
3038+
// let randomCol = collectionRef()
3039+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3040+
//
3041+
// let pipeline = db.pipeline()
3042+
// .collection(randomCol.path)
3043+
// .limit(1)
3044+
// .select([Constant(5).bitOr(12).as("result")])
3045+
// let snapshot = try await pipeline.execute()
3046+
// TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 13]], enforceOrder: false)
3047+
// }
3048+
//
3049+
// func testBitXor() async throws {
3050+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3051+
// let db = firestore()
3052+
// let randomCol = collectionRef()
3053+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3054+
//
3055+
// let pipeline = db.pipeline()
3056+
// .collection(randomCol.path)
3057+
// .limit(1)
3058+
// .select([Constant(5).bitXor(12).as("result")])
3059+
// let snapshot = try await pipeline.execute()
3060+
// TestHelper.compare(pipelineSnapshot: snapshot, expected: [["result": 9]], enforceOrder: false)
3061+
// }
3062+
//
3063+
// func testBitNot() async throws {
3064+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3065+
// let db = firestore()
3066+
// let randomCol = collectionRef()
3067+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3068+
// let bytesInput = Data([0xFD])
3069+
// let expectedOutput = Data([0x02])
3070+
//
3071+
// let pipeline = db.pipeline()
3072+
// .collection(randomCol.path)
3073+
// .limit(1)
3074+
// .select([Constant(bytesInput).bitNot().as("result")])
3075+
// let snapshot = try await pipeline.execute()
3076+
// TestHelper.compare(
3077+
// pipelineSnapshot: snapshot,
3078+
// expected: [["result": expectedOutput]],
3079+
// enforceOrder: false
3080+
// )
3081+
// }
3082+
//
3083+
// func testBitLeftShift() async throws {
3084+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3085+
// let db = firestore()
3086+
// let randomCol = collectionRef()
3087+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3088+
// let bytesInput = Data([0x02])
3089+
// let expectedOutput = Data([0x08])
3090+
//
3091+
// let pipeline = db.pipeline()
3092+
// .collection(randomCol.path)
3093+
// .limit(1)
3094+
// .select([Constant(bytesInput).bitLeftShift(2).as("result")])
3095+
// let snapshot = try await pipeline.execute()
3096+
// TestHelper.compare(
3097+
// pipelineSnapshot: snapshot,
3098+
// expected: [["result": expectedOutput]],
3099+
// enforceOrder: false
3100+
// )
3101+
// }
3102+
//
3103+
// func testBitRightShift() async throws {
3104+
// try XCTSkipIf(true, "Skip this test since backend has not yet supported.")
3105+
// let db = firestore()
3106+
// let randomCol = collectionRef()
3107+
// try await randomCol.document("dummyDoc").setData(["field": "value"])
3108+
// let bytesInput = Data([0x02])
3109+
// let expectedOutput = Data([0x00])
3110+
//
3111+
// let pipeline = db.pipeline()
3112+
// .collection(randomCol.path)
3113+
// .limit(1)
3114+
// .select([Constant(bytesInput).bitRightShift(2).as("result")])
3115+
// let snapshot = try await pipeline.execute()
3116+
// TestHelper.compare(
3117+
// pipelineSnapshot: snapshot,
3118+
// expected: [["result": expectedOutput]],
3119+
// enforceOrder: false
3120+
// )
3121+
// }
30963122

30973123
func testDocumentId() async throws {
30983124
try XCTSkipIf(true, "Skip this test since backend has not yet supported.")

0 commit comments

Comments
 (0)