Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Examples/Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,8 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_UPCOMING_FEATURE_EXISTENTIAL_ANY = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 6.0;
};
name = Debug;
Expand Down Expand Up @@ -1128,6 +1130,8 @@
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_UPCOMING_FEATURE_EXISTENTIAL_ANY = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 6.0;
VALIDATE_PRODUCT = YES;
};
Expand Down Expand Up @@ -1435,7 +1439,7 @@
/* Begin XCLocalSwiftPackageReference section */
CA9102E92E1F299900F85DD0 /* XCLocalSwiftPackageReference ".." */ = {
isa = XCLocalSwiftPackageReference;
relativePath = "..";
relativePath = ..;
};
/* End XCLocalSwiftPackageReference section */

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 3 additions & 9 deletions Examples/Reminders/RemindersApp.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import CloudKit
import Combine
import Dependencies
import SharingGRDB
import SwiftUI
import UIKit
Expand All @@ -12,15 +14,7 @@ struct RemindersApp: App {
init() {
if context == .live {
try! prepareDependencies {
$0.defaultDatabase = try Reminders.appDatabase()
$0.defaultSyncEngine = try SyncEngine(
for: $0.defaultDatabase,
tables: RemindersList.self,
RemindersListAsset.self,
Reminder.self,
Tag.self,
ReminderTag.self
)
try $0.bootstrapDatabase()
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions Examples/Reminders/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ struct ReminderTag: Hashable, Identifiable {
var tagID: Tag.ID
}

extension DependencyValues {
mutating func bootstrapDatabase() throws {
defaultDatabase = try Reminders.appDatabase()
defaultSyncEngine = try SyncEngine(
for: defaultDatabase,
tables: RemindersList.self,
RemindersListAsset.self,
Reminder.self,
Tag.self,
ReminderTag.self
)
}
}

func appDatabase() throws -> any DatabaseWriter {
@Dependency(\.context) var context
let database: any DatabaseWriter
Expand Down
1 change: 1 addition & 0 deletions Examples/Reminders/TagsForm.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import SharingGRDB
import SwiftUI
import SwiftUINavigation

struct TagsView: View {
@Fetch(Tags()) var tags = Tags.Value()
Expand Down
43 changes: 23 additions & 20 deletions Examples/RemindersTests/Internal.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Dependencies
import DependenciesTestSupport
import Foundation
import SharingGRDB
import SnapshotTesting
import SwiftUI
import Testing

Expand All @@ -8,7 +11,7 @@ import Testing
@Suite(
.dependencies {
$0.date.now = baseDate
$0.defaultDatabase = try Reminders.appDatabase()
try $0.bootstrapDatabase()
try $0.defaultDatabase.write { try $0.seedTestData() }
},
.snapshots(record: .failed)
Expand Down Expand Up @@ -132,25 +135,25 @@ extension Database {
remindersListID: UUID(2),
title: "Prepare for WWDC"
)
Tag(id: UUID(0), title: "car")
Tag(id: UUID(1), title: "kids")
Tag(id: UUID(2), title: "someday")
Tag(id: UUID(3), title: "optional")
Tag(id: UUID(4), title: "social")
Tag(id: UUID(5), title: "night")
Tag(id: UUID(6), title: "adulting")
ReminderTag.Draft(reminderID: UUID(0), tagID: UUID(2))
ReminderTag.Draft(reminderID: UUID(0), tagID: UUID(3))
ReminderTag.Draft(reminderID: UUID(0), tagID: UUID(6))
ReminderTag.Draft(reminderID: UUID(1), tagID: UUID(2))
ReminderTag.Draft(reminderID: UUID(1), tagID: UUID(3))
ReminderTag.Draft(reminderID: UUID(2), tagID: UUID(6))
ReminderTag.Draft(reminderID: UUID(3), tagID: UUID(0))
ReminderTag.Draft(reminderID: UUID(3), tagID: UUID(1))
ReminderTag.Draft(reminderID: UUID(4), tagID: UUID(4))
ReminderTag.Draft(reminderID: UUID(3), tagID: UUID(4))
ReminderTag.Draft(reminderID: UUID(10), tagID: UUID(4))
ReminderTag.Draft(reminderID: UUID(4), tagID: UUID(5))
Tag(title: "car")
Tag(title: "kids")
Tag(title: "someday")
Tag(title: "optional")
Tag(title: "social")
Tag(title: "night")
Tag(title: "adulting")
ReminderTag.Draft(reminderID: UUID(0), tagID: "someday")
ReminderTag.Draft(reminderID: UUID(0), tagID: "optional")
ReminderTag.Draft(reminderID: UUID(0), tagID: "adulting")
ReminderTag.Draft(reminderID: UUID(1), tagID: "someday")
ReminderTag.Draft(reminderID: UUID(1), tagID: "optional")
ReminderTag.Draft(reminderID: UUID(2), tagID: "adulting")
ReminderTag.Draft(reminderID: UUID(3), tagID: "car")
ReminderTag.Draft(reminderID: UUID(3), tagID: "kids")
ReminderTag.Draft(reminderID: UUID(4), tagID: "social")
ReminderTag.Draft(reminderID: UUID(3), tagID: "social")
ReminderTag.Draft(reminderID: UUID(10), tagID: "social")
ReminderTag.Draft(reminderID: UUID(4), tagID: "night")
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions Examples/RemindersTests/RemindersDetailsTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Dependencies
import DependenciesTestSupport
import GRDB
import InlineSnapshotTesting
import SharingGRDB
import SnapshotTestingCustomDump
import Testing

Expand Down
2 changes: 2 additions & 0 deletions Examples/RemindersTests/RemindersListsTests.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import GRDB
import InlineSnapshotTesting
import SharingGRDB
import SnapshotTestingCustomDump
import Testing

Expand Down
2 changes: 2 additions & 0 deletions Examples/RemindersTests/SearchRemindersTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Dependencies
import DependenciesTestSupport
import InlineSnapshotTesting
import GRDB
import SharingGRDB
import SnapshotTestingCustomDump
import Testing

Expand Down
26 changes: 26 additions & 0 deletions Sources/SharingGRDBCore/CloudKit/Internal/DatetimeGenerator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Dependencies
import Foundation

package struct DatetimeGenerator: DependencyKey, Sendable {
private var generate: @Sendable () -> Date
package var now: Date {
get { self.generate() }
set { self.generate = { newValue } }
}
package func callAsFunction() -> Date {
self.generate()
}
package static var liveValue: DatetimeGenerator {
Self { Date() }
}
package static var testValue: DatetimeGenerator {
Self { Date() }
}
}

extension DependencyValues {
package var datetime: DatetimeGenerator {
get { self[DatetimeGenerator.self] }
set { self[DatetimeGenerator.self] = newValue }
}
}
101 changes: 101 additions & 0 deletions Sources/SharingGRDBCore/CloudKit/Internal/MockCloudContainer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import CustomDump
import CloudKit

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
package final class MockCloudContainer: CloudContainer, CustomDumpReflectable {
package let _accountStatus: LockIsolated<CKAccountStatus>
package let containerIdentifier: String?
package let privateCloudDatabase: MockCloudDatabase
package let sharedCloudDatabase: MockCloudDatabase

package init(
accountStatus: CKAccountStatus = .available,
containerIdentifier: String?,
privateCloudDatabase: MockCloudDatabase,
sharedCloudDatabase: MockCloudDatabase
) {
self._accountStatus = LockIsolated(accountStatus)
self.containerIdentifier = containerIdentifier
self.privateCloudDatabase = privateCloudDatabase
self.sharedCloudDatabase = sharedCloudDatabase
}

package func accountStatus() -> CKAccountStatus {
_accountStatus.withValue(\.self)
}

package var rawValue: CKContainer {
fatalError("This should never be called in tests.")
}

package func accountStatus() async throws -> CKAccountStatus {
_accountStatus.withValue { $0 }
}

package func shareMetadata(for url: URL, shouldFetchRootRecord: Bool) async throws -> CKShare.Metadata {
fatalError()
}

package func accept(_ metadata: CKShare.Metadata) async throws -> CKShare {
fatalError()
}

package static func createContainer(identifier containerIdentifier: String) -> MockCloudContainer {
@Dependency(\.mockCloudContainers) var mockCloudContainers
return mockCloudContainers.withValue { storage in
let container: MockCloudContainer
if let existingContainer = storage[containerIdentifier] {
container = existingContainer
} else {
container = MockCloudContainer(
accountStatus: .available,
containerIdentifier: containerIdentifier,
privateCloudDatabase: MockCloudDatabase(databaseScope: .private),
sharedCloudDatabase: MockCloudDatabase(databaseScope: .shared)
)
container.privateCloudDatabase.set(container: container)
container.sharedCloudDatabase.set(container: container)
}
storage[containerIdentifier] = container
return container
}
}

package static func == (lhs: MockCloudContainer, rhs: MockCloudContainer) -> Bool {
lhs === rhs
}

package func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}

package var customDumpMirror: Mirror {
Mirror.init(
self,
children: [
("privateCloudDatabase", privateCloudDatabase),
("sharedCloudDatabase", sharedCloudDatabase),
],
displayStyle: .struct
)
}
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
private enum MockCloudContainersKey: TestDependencyKey {
static var testValue: LockIsolated<[String: MockCloudContainer]> {
LockIsolated<[String: MockCloudContainer]>([:])
}
}

extension DependencyValues {
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
fileprivate var mockCloudContainers: LockIsolated<[String: MockCloudContainer]> {
get {
self[MockCloudContainersKey.self]
}
set {
self[MockCloudContainersKey.self] = newValue
}
}
}
Loading
Loading