add iOS
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
import XCTest
|
||||
import GRDB
|
||||
|
||||
private struct AppConfiguration: Codable {
|
||||
// Support for the single row guarantee
|
||||
private var id = 1
|
||||
|
||||
// The configuration properties
|
||||
var text: String
|
||||
// ... other properties
|
||||
|
||||
init(text: String) {
|
||||
self.text = text
|
||||
}
|
||||
}
|
||||
|
||||
extension AppConfiguration {
|
||||
/// The default configuration
|
||||
static let `default` = AppConfiguration(text: "default")
|
||||
}
|
||||
|
||||
// Database Access
|
||||
extension AppConfiguration: FetchableRecord, PersistableRecord {
|
||||
// Customize the default PersistableRecord behavior
|
||||
func willUpdate(_ db: Database, columns: Set<String>) throws {
|
||||
// Insert the default configuration if it does not exist yet.
|
||||
if try !exists(db) {
|
||||
try AppConfiguration.default.insert(db)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the persisted configuration, or the default one if the
|
||||
/// database table is empty.
|
||||
static func find(_ db: Database) throws -> AppConfiguration {
|
||||
try fetchOne(db) ?? .default
|
||||
}
|
||||
}
|
||||
|
||||
class SingletonRecordTest: GRDBTestCase {
|
||||
private func createEmptyAppConfigurationTable(_ db: Database) throws {
|
||||
// Table creation
|
||||
try db.create(table: "appConfiguration") { t in
|
||||
// Single row guarantee
|
||||
t.primaryKey("id", .integer, onConflict: .replace).check { $0 == 1 }
|
||||
|
||||
// The configuration columns
|
||||
t.column("text", .text).notNull()
|
||||
// ... other columns
|
||||
}
|
||||
}
|
||||
|
||||
func test_fetch_from_empty_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
let config = try AppConfiguration.find(db)
|
||||
// Then
|
||||
XCTAssertEqual(config.text, "default")
|
||||
}
|
||||
}
|
||||
|
||||
func test_fetch_from_populated_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
let config = try AppConfiguration.find(db)
|
||||
// Then
|
||||
XCTAssertEqual(config.text, "initial")
|
||||
}
|
||||
}
|
||||
|
||||
func test_insert_in_empty_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").insert(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_insert_in_populated_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").insert(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_update_in_empty_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").update(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_update_in_populated_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").update(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_update_changes_in_empty_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
var config = try AppConfiguration.find(db)
|
||||
try config.updateChanges(db) {
|
||||
$0.text = "test"
|
||||
}
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_update_changes_in_populated_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
var config = try AppConfiguration.find(db)
|
||||
try config.updateChanges(db) {
|
||||
$0.text = "test"
|
||||
}
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_save_in_empty_database() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").save(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_save_in_populated() throws {
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").save(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_upsert_in_empty_database() throws {
|
||||
#if GRDBCUSTOMSQLITE || GRDBCIPHER
|
||||
guard sqlite3_libversion_number() >= 3035000 else {
|
||||
throw XCTSkip("UPSERT is not available")
|
||||
}
|
||||
#else
|
||||
guard #available(iOS 15, macOS 12, tvOS 15, watchOS 8, *) else {
|
||||
throw XCTSkip("UPSERT is not available")
|
||||
}
|
||||
#endif
|
||||
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").upsert(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
|
||||
func test_upsert_in_populated_database() throws {
|
||||
#if GRDBCUSTOMSQLITE || GRDBCIPHER
|
||||
guard sqlite3_libversion_number() >= 3035000 else {
|
||||
throw XCTSkip("UPSERT is not available")
|
||||
}
|
||||
#else
|
||||
guard #available(iOS 15, macOS 12, tvOS 15, watchOS 8, *) else {
|
||||
throw XCTSkip("UPSERT is not available")
|
||||
}
|
||||
#endif
|
||||
|
||||
try makeDatabaseQueue().write { db in
|
||||
// Given
|
||||
try createEmptyAppConfigurationTable(db)
|
||||
try AppConfiguration(text: "initial").insert(db)
|
||||
// When
|
||||
try AppConfiguration(text: "test").upsert(db)
|
||||
// Then
|
||||
try XCTAssertEqual(AppConfiguration.find(db).text, "test")
|
||||
let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration"))
|
||||
XCTAssertEqual(row, ["id": 1, "text": "test"])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user