Skip to content

Commit e5993c4

Browse files
committed
Merge branch 'batch-create-fails-with-parent-context-rollback' into 3.0-preview
# Conflicts: # Tests/CoreDataRepositoryTests/CRUDRepositoryTests.swift
2 parents 9224f52 + cd58bc8 commit e5993c4

3 files changed

Lines changed: 36 additions & 4 deletions

File tree

Sources/CoreDataRepository/CoreDataRepository+CRUD.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ extension CoreDataRepository {
1717
) async -> Result<Model, CoreDataError> {
1818
await context.performInScratchPad(schedule: .enqueued) { [context] scratchPad in
1919
let object = Model.ManagedModel(context: scratchPad)
20+
let tempObjectId = object.objectID
2021
try item.updating(managed: object)
2122
try scratchPad.save()
2223
try context.performAndWait {
2324
context.transactionAuthor = transactionAuthor
24-
try context.save()
25+
do {
26+
try context.save()
27+
} catch {
28+
let parentContextObject = context.object(with: tempObjectId)
29+
context.delete(parentContextObject)
30+
throw error
31+
}
2532
context.transactionAuthor = nil
2633
}
2734
try scratchPad.obtainPermanentIDs(for: [object])

Tests/CoreDataRepositoryTests/CRUDRepositoryTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,31 @@ final class CRUDRepositoryTests: CoreDataXCTestCase {
3131
try verify(transactionAuthor: transactionAuthor, timeStamp: historyTimeStamp)
3232
}
3333

34+
func testCreateFailure() async throws {
35+
let historyTimeStamp = Date()
36+
let transactionAuthor: String = #function
37+
let movie = Movie(id: UUID(), title: "Create Success", releaseDate: Date(), boxOffice: 100)
38+
var existingMovie = try await repositoryContext().perform(schedule: .immediate) {
39+
let object = try ManagedMovie(context: self.repositoryContext())
40+
try movie.updating(managed: object)
41+
try self.repositoryContext().save()
42+
return try Movie(managed: object)
43+
}
44+
var tempResultMovie = existingMovie
45+
XCTAssertNotNil(tempResultMovie.url)
46+
tempResultMovie.url = nil
47+
XCTAssertNoDifference(tempResultMovie, movie)
48+
49+
try await verify(existingMovie)
50+
51+
let result: Result<Movie, CoreDataError> = try await repository()
52+
.create(movie, transactionAuthor: transactionAuthor)
53+
guard case .failure = result else {
54+
XCTFail("Expecting a failed result")
55+
return
56+
}
57+
}
58+
3459
func testReadSuccess() async throws {
3560
let movie = Movie(id: UUID(), title: "Read Success", releaseDate: Date(), boxOffice: 100)
3661
let createdMovie: Movie = try await repositoryContext().perform(schedule: .immediate) {

Tests/CoreDataRepositoryTests/Movie.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ extension ManagedMovie {
7272
desc.name = "ManagedMovie"
7373
desc.managedObjectClassName = NSStringFromClass(ManagedMovie.self)
7474
desc.properties = [
75-
iDDescription,
75+
idDescription,
7676
titleDescription,
7777
releaseDateDescription,
7878
boxOfficeDescription,
7979
]
80-
desc.uniquenessConstraints = [[iDDescription]]
80+
desc.uniquenessConstraints = [[idDescription]]
8181
return desc
8282
}()
8383

84-
private static var iDDescription: NSAttributeDescription {
84+
private static var idDescription: NSAttributeDescription {
8585
let desc = NSAttributeDescription()
8686
desc.name = "id"
8787
desc.attributeType = .UUIDAttributeType

0 commit comments

Comments
 (0)