Skip to content

Commit a1c6ea5

Browse files
authored
Merge branch 'main' into main
2 parents f83458c + 540dc48 commit a1c6ea5

File tree

6 files changed

+48
-20
lines changed

6 files changed

+48
-20
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Release Notes
22

3+
## v0.11.0
4+
5+
Released on 2025/03/15
6+
7+
- **New**: adds QueryableOptions.assertNoFailure to treat errors as fatalError by [@ChristophKaser](https://github.com/ChristophKaser) in [#64](https://github.com/groue/GRDBQuery/pull/64)
8+
39
## v0.10.1
410

511
Released on 2024/09/29

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GRDBQuery
22

3-
**Latest release**: September 29, 2024[version 0.10.1](https://github.com/groue/GRDBQuery/tree/0.10.1)[CHANGELOG](CHANGELOG.md)
3+
**Latest release**: March 15, 2025[version 0.11.0](https://github.com/groue/GRDBQuery/tree/0.11.0)[CHANGELOG](CHANGELOG.md)
44

55
**Requirements**: iOS 14.0+ / macOS 11+ / tvOS 14.0+ / watchOS 7.0+ • Swift 6+ / Xcode 16+
66

Sources/GRDBQuery/Queryable+DatabaseContext/FetchQueryable.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ extension TopLevelDatabaseReader {
5555
.eraseToAnyPublisher()
5656
}
5757
}
58+
.assertNoFailure(if: queryableOptions.contains(.assertNoFailure))
5859
.eraseToAnyPublisher()
5960
}
6061
}

Sources/GRDBQuery/Queryable+DatabaseContext/QueryableOptions.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
///
88
/// - ``async``
99
/// - ``constantRegion``
10+
/// - ``assertNoFailure``
1011
public struct QueryableOptions: OptionSet, Sendable {
1112
public let rawValue: Int
1213

@@ -58,6 +59,12 @@ public struct QueryableOptions: OptionSet, Sendable {
5859
/// ``PresenceObservationQueryable`` types.
5960
public static let constantRegion = QueryableOptions(rawValue: 1 << 1)
6061

62+
/// By default, any error that occurs can be accessed using ``Query/Wrapper/error``
63+
/// and is otherwise ignored.
64+
/// With this option, errors that happen while accessing the
65+
/// database terminate the app with a fatal error.
66+
public static let assertNoFailure = QueryableOptions(rawValue: 1 << 2)
67+
6168
/// The default options.
6269
public static let `default`: QueryableOptions = []
6370
}

Sources/GRDBQuery/Queryable+DatabaseContext/ValueObservationQueryable.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,24 @@ extension TopLevelDatabaseReader {
6868
.eraseToAnyPublisher()
6969
}
7070
}
71+
.assertNoFailure(if: queryableOptions.contains(.assertNoFailure))
7172
.eraseToAnyPublisher()
7273
}
7374
}
7475

76+
77+
extension Publisher {
78+
func assertNoFailure(if condition: Bool) -> AnyPublisher<Output, Failure> {
79+
if !condition {
80+
self.eraseToAnyPublisher()
81+
} else {
82+
self.assertNoFailure()
83+
.setFailureType(to: Failure.self)
84+
.eraseToAnyPublisher()
85+
}
86+
}
87+
}
88+
7589
#if DEBUG
7690
import SwiftUI
7791

Tests/QueryTests/QueryTestsUITests/QueryTestsUITests.swift

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class QueryTestsUITests: XCTestCase {
2525
app.buttons[XCUIIdentifierFullScreenWindow].tap()
2626
}
2727

28-
app.tabs["Tab 1"].tap()
28+
app.radioButtons["Tab 1"].tap()
2929

3030
let text = app.staticTexts["default.value"]
3131
let changeRequestButton = app.buttons["default.changeRequestButton"]
@@ -74,7 +74,7 @@ class QueryTestsUITests: XCTestCase {
7474
app.buttons[XCUIIdentifierFullScreenWindow].tap()
7575
}
7676

77-
app.tabs["Tab 1"].tap()
77+
app.radioButtons["Tab 1"].tap()
7878

7979
let text = app.staticTexts["initial.value"]
8080
let changeRequestButton = app.buttons["initial.changeRequestButton"]
@@ -123,7 +123,7 @@ class QueryTestsUITests: XCTestCase {
123123
app.buttons[XCUIIdentifierFullScreenWindow].tap()
124124
}
125125

126-
app.tabs["Tab 1"].tap()
126+
app.radioButtons["Tab 1"].tap()
127127

128128
let text = app.staticTexts["constant.value"]
129129
let changeRequestButton = app.buttons["constant.changeRequestButton"]
@@ -172,7 +172,7 @@ class QueryTestsUITests: XCTestCase {
172172
app.buttons[XCUIIdentifierFullScreenWindow].tap()
173173
}
174174

175-
app.tabs["Tab 1"].tap()
175+
app.radioButtons["Tab 1"].tap()
176176

177177
let text = app.staticTexts["binding.value"]
178178
let changeRequestButton = app.buttons["binding.changeRequestButton"]
@@ -222,20 +222,20 @@ class QueryTestsUITests: XCTestCase {
222222
let notificationButton = app.buttons["queryObservation.always.notificationButton"]
223223
let sharedNotificationButton = app.buttons["shared.notificationButton"]
224224

225-
app.tabs["queryObservation.always"].tap()
226-
app.tabs["Tab 1"].tap()
225+
app.radioButtons["queryObservation.always"].tap()
226+
app.radioButtons["Tab 1"].tap()
227227
sharedNotificationButton.tap()
228228

229-
app.tabs["queryObservation.always"].tap()
229+
app.radioButtons["queryObservation.always"].tap()
230230
XCTAssertEqual(text.value as? String, "7")
231231

232232
notificationButton.tap()
233233
XCTAssertEqual(text.value as? String, "8")
234234

235-
app.tabs["Tab 1"].tap()
235+
app.radioButtons["Tab 1"].tap()
236236
sharedNotificationButton.tap()
237237

238-
app.tabs["queryObservation.always"].tap()
238+
app.radioButtons["queryObservation.always"].tap()
239239
XCTAssertEqual(text.value as? String, "9")
240240
}
241241

@@ -253,20 +253,20 @@ class QueryTestsUITests: XCTestCase {
253253
let notificationButton = app.buttons["queryObservation.onRender.notificationButton"]
254254
let sharedNotificationButton = app.buttons["shared.notificationButton"]
255255

256-
app.tabs["queryObservation.onRender"].tap()
257-
app.tabs["Tab 1"].tap()
256+
app.radioButtons["queryObservation.onRender"].tap()
257+
app.radioButtons["Tab 1"].tap()
258258
sharedNotificationButton.tap()
259259

260-
app.tabs["queryObservation.onRender"].tap()
260+
app.radioButtons["queryObservation.onRender"].tap()
261261
XCTAssertEqual(text.value as? String, "6")
262262

263263
notificationButton.tap()
264264
XCTAssertEqual(text.value as? String, "7")
265265

266-
app.tabs["Tab 1"].tap()
266+
app.radioButtons["Tab 1"].tap()
267267
sharedNotificationButton.tap()
268268

269-
app.tabs["queryObservation.onRender"].tap()
269+
app.radioButtons["queryObservation.onRender"].tap()
270270
XCTAssertEqual(text.value as? String, "6")
271271
}
272272

@@ -283,20 +283,20 @@ class QueryTestsUITests: XCTestCase {
283283
let notificationButton = app.buttons["queryObservation.onAppear.notificationButton"]
284284
let sharedNotificationButton = app.buttons["shared.notificationButton"]
285285

286-
app.tabs["queryObservation.onAppear"].tap()
287-
app.tabs["Tab 1"].tap()
286+
app.radioButtons["queryObservation.onAppear"].tap()
287+
app.radioButtons["Tab 1"].tap()
288288
sharedNotificationButton.tap()
289289

290-
app.tabs["queryObservation.onAppear"].tap()
290+
app.radioButtons["queryObservation.onAppear"].tap()
291291
XCTAssertEqual(text.value as? String, "6")
292292

293293
notificationButton.tap()
294294
XCTAssertEqual(text.value as? String, "7")
295295

296-
app.tabs["Tab 1"].tap()
296+
app.radioButtons["Tab 1"].tap()
297297
sharedNotificationButton.tap()
298298

299-
app.tabs["queryObservation.onAppear"].tap()
299+
app.radioButtons["queryObservation.onAppear"].tap()
300300
XCTAssertEqual(text.value as? String, "6")
301301
}
302302
}

0 commit comments

Comments
 (0)