Skip to content

Commit 515bd78

Browse files
committed
Failing test for groue#1746
1 parent f2aa6b3 commit 515bd78

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

Tests/GRDBTests/ValueObservationTests.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,4 +1352,58 @@ class ValueObservationTests: GRDBTestCase {
13521352
XCTAssertEqual(value, true)
13531353
})
13541354
}
1355+
1356+
// Regression test for <https://github.com/groue/GRDB.swift/discussions/1746>
1357+
@MainActor func testIssue1746() async throws {
1358+
let dbQueue = try makeDatabaseQueue()
1359+
try await dbQueue.write { db in
1360+
try db.execute(sql: "CREATE TABLE test (id INTEGER PRIMARY KEY)")
1361+
}
1362+
1363+
// Start a task that waits for writeContinuation before it writes.
1364+
let (writeStream, writeContinuation) = AsyncStream.makeStream(of: Void.self)
1365+
let task = Task {
1366+
for await _ in writeStream { }
1367+
try? await dbQueue.write { db in
1368+
XCTAssertFalse(Task.isCancelled) // Required for the test to be meaningful
1369+
try db.execute(sql: "INSERT INTO test DEFAULT VALUES")
1370+
}
1371+
}
1372+
1373+
// A transaction observer that cancels a Task after commit.
1374+
class CancelObserver: TransactionObserver {
1375+
let task: Task<Void, Never>
1376+
init(task: Task<Void, Never>) {
1377+
self.task = task
1378+
}
1379+
func observes(eventsOfKind eventKind: DatabaseEventKind) -> Bool { true }
1380+
func databaseDidChange(with event: DatabaseEvent) { }
1381+
func databaseDidRollback(_ db: Database) { }
1382+
func databaseDidCommit(_ db: Database) {
1383+
task.cancel()
1384+
}
1385+
}
1386+
1387+
// Register CancelObserver first, so no other observer could access
1388+
// the database before the task is cancelled.
1389+
dbQueue.add(transactionObserver: CancelObserver(task: task), extent: .databaseLifetime)
1390+
1391+
// Start observing.
1392+
// We expect to see 0, then 1.
1393+
let values = ValueObservation
1394+
.tracking(Table("test").fetchCount)
1395+
.values(in: dbQueue)
1396+
for try await value in values {
1397+
if value == 0 {
1398+
// Perform the write.
1399+
writeContinuation.finish()
1400+
} else if value == 1 {
1401+
// Test passes
1402+
break
1403+
} else {
1404+
XCTFail("Unexpected value \(value)")
1405+
break
1406+
}
1407+
}
1408+
}
13551409
}

0 commit comments

Comments
 (0)