diff --git a/GRDB.xcodeproj/project.pbxproj b/GRDB.xcodeproj/project.pbxproj index 28ecb12530..9c13f9eb07 100755 --- a/GRDB.xcodeproj/project.pbxproj +++ b/GRDB.xcodeproj/project.pbxproj @@ -276,6 +276,7 @@ 56AFEF2F29969F6E00CA1E51 /* TransactionClock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AFEF2E29969F6E00CA1E51 /* TransactionClock.swift */; }; 56AFEF372996B9DC00CA1E51 /* TransactionDateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AFEF362996B9DC00CA1E51 /* TransactionDateTests.swift */; }; 56B021C91D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B021C81D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift */; }; + 56B6AB062BD3DCAC009A0B71 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6AB052BD3DCAC009A0B71 /* SingletonUserDefaultsTest.swift */; }; 56B6EF56208CB4E3002F0ACB /* ColumnExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6EF55208CB4E3002F0ACB /* ColumnExpressionTests.swift */; }; 56B7EE832863781300C0525F /* WALSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B7EE822863781300C0525F /* WALSnapshot.swift */; }; 56B7F43A1BEB42D500E39BBF /* Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B7F4391BEB42D500E39BBF /* Migration.swift */; }; @@ -770,6 +771,7 @@ 56AFEF362996B9DC00CA1E51 /* TransactionDateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDateTests.swift; sourceTree = ""; }; 56B021C81D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MutablePersistableRecordPersistenceConflictPolicyTests.swift; sourceTree = ""; }; 56B14E7E1D4DAE54000BF4A3 /* RowFromDictionaryLiteralTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowFromDictionaryLiteralTests.swift; sourceTree = ""; }; + 56B6AB052BD3DCAC009A0B71 /* SingletonUserDefaultsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingletonUserDefaultsTest.swift; sourceTree = ""; }; 56B6EF55208CB4E3002F0ACB /* ColumnExpressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColumnExpressionTests.swift; sourceTree = ""; }; 56B7EE822863781300C0525F /* WALSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WALSnapshot.swift; sourceTree = ""; }; 56B7F4291BE14A1900E39BBF /* CGFloatTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatTests.swift; sourceTree = ""; }; @@ -1552,6 +1554,7 @@ children = ( 564E73DE203D50B9000C443C /* JoinSupportTests.swift */, 5616B4FA28B5F5220052017E /* SingletonRecordTest.swift */, + 56B6AB052BD3DCAC009A0B71 /* SingletonUserDefaultsTest.swift */, 5674A7251F30A8EF0095F066 /* FetchableRecord */, 560B3FA41C19DFF800C58EC7 /* PersistableRecord */, 56176C9E1EACEDF9000F3F2B /* Record */, @@ -2086,6 +2089,7 @@ 562393181DECC02000A6B01F /* RowFetchTests.swift in Sources */, 56677C0D241CD0D00050755D /* ValueObservationRecorder.swift in Sources */, 5653EADA20944B4F00F46237 /* AssociationRowScopeSearchTests.swift in Sources */, + 56B6AB062BD3DCAC009A0B71 /* SingletonUserDefaultsTest.swift in Sources */, 563B5336267E2F90009549B5 /* TableTests.swift in Sources */, 56D4965A1D81304E008276D7 /* FoundationNSDataTests.swift in Sources */, 56D496791D81309E008276D7 /* RecordWithColumnNameManglingTests.swift in Sources */, diff --git a/GRDBCustom.xcodeproj/project.pbxproj b/GRDBCustom.xcodeproj/project.pbxproj index a0888b0b42..253e90b00e 100755 --- a/GRDBCustom.xcodeproj/project.pbxproj +++ b/GRDBCustom.xcodeproj/project.pbxproj @@ -267,6 +267,7 @@ 56AFEF3A2996B9EE00CA1E51 /* TransactionDateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AFEF382996B9EE00CA1E51 /* TransactionDateTests.swift */; }; 56B021CC1D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B021C81D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift */; }; 56B14E821D4DAE54000BF4A3 /* RowFromDictionaryLiteralTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B14E7E1D4DAE54000BF4A3 /* RowFromDictionaryLiteralTests.swift */; }; + 56B6AB092BD3DCE0009A0B71 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6AB072BD3DCE0009A0B71 /* SingletonUserDefaultsTest.swift */; }; 56B6EF60208CB746002F0ACB /* ColumnExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6EF5E208CB746002F0ACB /* ColumnExpressionTests.swift */; }; 56B86E70220FF4C900524C16 /* SQLLiteralTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B86E6E220FF4C800524C16 /* SQLLiteralTests.swift */; }; 56B9649F1DA51B4C0002DA19 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B9649C1DA51B4C0002DA19 /* FTS5.swift */; }; @@ -783,6 +784,7 @@ 56AFEF382996B9EE00CA1E51 /* TransactionDateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDateTests.swift; sourceTree = ""; }; 56B021C81D8C0D3900B239BB /* MutablePersistableRecordPersistenceConflictPolicyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MutablePersistableRecordPersistenceConflictPolicyTests.swift; sourceTree = ""; }; 56B14E7E1D4DAE54000BF4A3 /* RowFromDictionaryLiteralTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowFromDictionaryLiteralTests.swift; sourceTree = ""; }; + 56B6AB072BD3DCE0009A0B71 /* SingletonUserDefaultsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingletonUserDefaultsTest.swift; sourceTree = ""; }; 56B6EF5E208CB746002F0ACB /* ColumnExpressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColumnExpressionTests.swift; sourceTree = ""; }; 56B7F4291BE14A1900E39BBF /* CGFloatTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGFloatTests.swift; sourceTree = ""; }; 56B7F4391BEB42D500E39BBF /* Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Migration.swift; sourceTree = ""; }; @@ -1558,6 +1560,7 @@ children = ( 564E73E7203DA278000C443C /* JoinSupportTests.swift */, 5616B4FE28B5F5490052017E /* SingletonRecordTest.swift */, + 56B6AB072BD3DCE0009A0B71 /* SingletonUserDefaultsTest.swift */, 5674A7251F30A8EF0095F066 /* FetchableRecord */, 560B3FA41C19DFF800C58EC7 /* PersistableRecord */, 56176C9E1EACEDF9000F3F2B /* Record */, @@ -2330,6 +2333,7 @@ 5698AC431DA2BED90056AF8C /* FTS3PatternTests.swift in Sources */, 563B533B267E2FA4009549B5 /* TableTests.swift in Sources */, 5653EB6E20961FB200F46237 /* AssociationBelongsToSQLDerivationTests.swift in Sources */, + 56B6AB092BD3DCE0009A0B71 /* SingletonUserDefaultsTest.swift in Sources */, 561F38F62AC9CE5A0051EEE9 /* DatabaseDataDecodingStrategyTests.swift in Sources */, 564CE5C621B8FFE600652B19 /* DatabaseRegionObservationTests.swift in Sources */, F3BA80E11CFB300F003DC1BA /* DatabaseValueConversionTests.swift in Sources */, diff --git a/Tests/CocoaPods/SQLCipher3/GRDBTests.xcodeproj/project.pbxproj b/Tests/CocoaPods/SQLCipher3/GRDBTests.xcodeproj/project.pbxproj index 89f7c12005..2869b204eb 100644 --- a/Tests/CocoaPods/SQLCipher3/GRDBTests.xcodeproj/project.pbxproj +++ b/Tests/CocoaPods/SQLCipher3/GRDBTests.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 5603CECF2AC8636E00CF097D /* JSONExpressionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5603CECE2AC8636E00CF097D /* JSONExpressionsTests.swift */; }; 5603CED02AC8636E00CF097D /* JSONExpressionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5603CECE2AC8636E00CF097D /* JSONExpressionsTests.swift */; }; + 56071DE52BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56071DE42BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift */; }; + 56071DE62BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56071DE42BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift */; }; 561F38DD2AC891710051EEE9 /* JSONColumnTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38DC2AC891710051EEE9 /* JSONColumnTests.swift */; }; 561F38DE2AC891710051EEE9 /* JSONColumnTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38DC2AC891710051EEE9 /* JSONColumnTests.swift */; }; 561F38F92AC9CE6D0051EEE9 /* DatabaseDataDecodingStrategyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38F72AC9CE6D0051EEE9 /* DatabaseDataDecodingStrategyTests.swift */; }; @@ -502,6 +504,7 @@ 04298D834C818285823558AB /* Pods-GRDBTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GRDBTests.release.xcconfig"; path = "Target Support Files/Pods-GRDBTests/Pods-GRDBTests.release.xcconfig"; sourceTree = ""; }; 47C5D1B9AFFE795AA1D6EA5D /* Pods-GRDBTestsEncrypted.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GRDBTestsEncrypted.release.xcconfig"; path = "Target Support Files/Pods-GRDBTestsEncrypted/Pods-GRDBTestsEncrypted.release.xcconfig"; sourceTree = ""; }; 5603CECE2AC8636E00CF097D /* JSONExpressionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONExpressionsTests.swift; sourceTree = ""; }; + 56071DE42BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingletonUserDefaultsTest.swift; sourceTree = ""; }; 561F38DC2AC891710051EEE9 /* JSONColumnTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONColumnTests.swift; sourceTree = ""; }; 561F38F72AC9CE6D0051EEE9 /* DatabaseDataDecodingStrategyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseDataDecodingStrategyTests.swift; sourceTree = ""; }; 561F38F82AC9CE6D0051EEE9 /* DatabaseDataEncodingStrategyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseDataEncodingStrategyTests.swift; sourceTree = ""; }; @@ -1034,6 +1037,7 @@ 56419CFA24A5405A004967E1 /* SelectStatementTests.swift */, 567B5C282AD32A2D00629622 /* SharedValueObservationTests.swift */, 567B5C1E2AD32A2D00629622 /* SingletonRecordTest.swift */, + 56071DE42BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift */, 567B5C232AD32A2D00629622 /* SQLExpressionIsConstantTests.swift */, 56419CCA24A54056004967E1 /* SQLExpressionLiteralTests.swift */, 567B5C1D2AD32A2D00629622 /* SQLIdentifyingColumnsTests.swift */, @@ -1459,6 +1463,7 @@ 56419E0324A54062004967E1 /* SchedulingWatchdogTests.swift in Sources */, 56419E7D24A54063004967E1 /* DropWhileCursorTests.swift in Sources */, 56419EBD24A54063004967E1 /* AssociationHasOneThroughSQLDerivationTests.swift in Sources */, + 56071DE52BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift in Sources */, 56419E8F24A54063004967E1 /* AssociationHasManySQLTests.swift in Sources */, 5641A1A424A540D6004967E1 /* Support.swift in Sources */, 5641A1BC24A540D6004967E1 /* PublisherExpectation.swift in Sources */, @@ -1706,6 +1711,7 @@ 56419E0424A54062004967E1 /* SchedulingWatchdogTests.swift in Sources */, 56419E7E24A54063004967E1 /* DropWhileCursorTests.swift in Sources */, 56419EBE24A54063004967E1 /* AssociationHasOneThroughSQLDerivationTests.swift in Sources */, + 56071DE62BD3DDB5000802B6 /* SingletonUserDefaultsTest.swift in Sources */, 56419E9024A54063004967E1 /* AssociationHasManySQLTests.swift in Sources */, 5641A1A524A540D6004967E1 /* Support.swift in Sources */, 5641A1BD24A540D6004967E1 /* PublisherExpectation.swift in Sources */, diff --git a/Tests/CocoaPods/SQLCipher4/GRDBTests.xcodeproj/project.pbxproj b/Tests/CocoaPods/SQLCipher4/GRDBTests.xcodeproj/project.pbxproj index 8fba6727d5..f8c3e463fe 100644 --- a/Tests/CocoaPods/SQLCipher4/GRDBTests.xcodeproj/project.pbxproj +++ b/Tests/CocoaPods/SQLCipher4/GRDBTests.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 56071DE22BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56071DE12BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift */; }; + 56071DE32BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56071DE12BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift */; }; 561F38E12AC891890051EEE9 /* JSONExpressionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38DF2AC891890051EEE9 /* JSONExpressionsTests.swift */; }; 561F38E22AC891890051EEE9 /* JSONExpressionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38DF2AC891890051EEE9 /* JSONExpressionsTests.swift */; }; 561F38E32AC891890051EEE9 /* JSONColumnTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 561F38E02AC891890051EEE9 /* JSONColumnTests.swift */; }; @@ -503,6 +505,7 @@ /* Begin PBXFileReference section */ 04298D834C818285823558AB /* Pods-GRDBTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GRDBTests.release.xcconfig"; path = "Target Support Files/Pods-GRDBTests/Pods-GRDBTests.release.xcconfig"; sourceTree = ""; }; 47C5D1B9AFFE795AA1D6EA5D /* Pods-GRDBTestsEncrypted.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GRDBTestsEncrypted.release.xcconfig"; path = "Target Support Files/Pods-GRDBTestsEncrypted/Pods-GRDBTestsEncrypted.release.xcconfig"; sourceTree = ""; }; + 56071DE12BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingletonUserDefaultsTest.swift; sourceTree = ""; }; 561F38DF2AC891890051EEE9 /* JSONExpressionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONExpressionsTests.swift; sourceTree = ""; }; 561F38E02AC891890051EEE9 /* JSONColumnTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONColumnTests.swift; sourceTree = ""; }; 561F38FD2AC9CE870051EEE9 /* DatabaseDataEncodingStrategyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseDataEncodingStrategyTests.swift; sourceTree = ""; }; @@ -1038,6 +1041,7 @@ 56419F5B24A54098004967E1 /* SelectStatementTests.swift */, 567B5C0B2AD32A0000629622 /* SharedValueObservationTests.swift */, 567B5C0A2AD32A0000629622 /* SingletonRecordTest.swift */, + 56071DE12BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift */, 567B5C0C2AD32A0000629622 /* SQLExpressionIsConstantTests.swift */, 56419F1C24A54094004967E1 /* SQLExpressionLiteralTests.swift */, 567B5C0D2AD32A0000629622 /* SQLIdentifyingColumnsTests.swift */, @@ -1465,6 +1469,7 @@ 5641A04424A540A1004967E1 /* FTS3TokenizerTests.swift in Sources */, 5641A14024A540A2004967E1 /* RecordPrimaryKeyRowIDTests.swift in Sources */, 561F38FF2AC9CE870051EEE9 /* DatabaseDataEncodingStrategyTests.swift in Sources */, + 56071DE22BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift in Sources */, 5641A08A24A540A1004967E1 /* EncryptionTests.swift in Sources */, 5641A11E24A540A1004967E1 /* IndexInfoTests.swift in Sources */, 56419FEC24A540A1004967E1 /* FTS4TableBuilderTests.swift in Sources */, @@ -1712,6 +1717,7 @@ 5641A04524A540A1004967E1 /* FTS3TokenizerTests.swift in Sources */, 5641A14124A540A2004967E1 /* RecordPrimaryKeyRowIDTests.swift in Sources */, 561F39002AC9CE870051EEE9 /* DatabaseDataEncodingStrategyTests.swift in Sources */, + 56071DE32BD3DDA5000802B6 /* SingletonUserDefaultsTest.swift in Sources */, 5641A08B24A540A1004967E1 /* EncryptionTests.swift in Sources */, 5641A11F24A540A1004967E1 /* IndexInfoTests.swift in Sources */, 56419FED24A540A1004967E1 /* FTS4TableBuilderTests.swift in Sources */, diff --git a/Tests/GRDBTests/SingletonRecordTest.swift b/Tests/GRDBTests/SingletonRecordTest.swift index ea8008c254..a3fb0766ee 100644 --- a/Tests/GRDBTests/SingletonRecordTest.swift +++ b/Tests/GRDBTests/SingletonRecordTest.swift @@ -31,7 +31,7 @@ extension AppConfiguration: FetchableRecord, PersistableRecord { /// Returns the persisted configuration, or the default one if the /// database table is empty. - static func fetch(_ db: Database) throws -> AppConfiguration { + static func find(_ db: Database) throws -> AppConfiguration { try fetchOne(db) ?? .default } } @@ -54,7 +54,7 @@ class SingletonRecordTest: GRDBTestCase { // Given try createEmptyAppConfigurationTable(db) // When - let config = try AppConfiguration.fetch(db) + let config = try AppConfiguration.find(db) // Then XCTAssertEqual(config.text, "default") } @@ -66,7 +66,7 @@ class SingletonRecordTest: GRDBTestCase { try createEmptyAppConfigurationTable(db) try AppConfiguration(text: "initial").insert(db) // When - let config = try AppConfiguration.fetch(db) + let config = try AppConfiguration.find(db) // Then XCTAssertEqual(config.text, "initial") } @@ -79,7 +79,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").insert(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -93,7 +93,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").insert(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -106,7 +106,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").update(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -120,7 +120,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").update(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -131,12 +131,12 @@ class SingletonRecordTest: GRDBTestCase { // Given try createEmptyAppConfigurationTable(db) // When - var config = try AppConfiguration.fetch(db) + var config = try AppConfiguration.find(db) try config.updateChanges(db) { $0.text = "test" } // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -148,12 +148,12 @@ class SingletonRecordTest: GRDBTestCase { try createEmptyAppConfigurationTable(db) try AppConfiguration(text: "initial").insert(db) // When - var config = try AppConfiguration.fetch(db) + var config = try AppConfiguration.find(db) try config.updateChanges(db) { $0.text = "test" } // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -166,7 +166,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").save(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -180,7 +180,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").save(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -203,7 +203,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").upsert(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } @@ -227,7 +227,7 @@ class SingletonRecordTest: GRDBTestCase { // When try AppConfiguration(text: "test").upsert(db) // Then - try XCTAssertEqual(AppConfiguration.fetch(db).text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) XCTAssertEqual(row, ["id": 1, "text": "test"]) } diff --git a/Tests/GRDBTests/SingletonUserDefaultsTest.swift b/Tests/GRDBTests/SingletonUserDefaultsTest.swift new file mode 100644 index 0000000000..7db9f80e31 --- /dev/null +++ b/Tests/GRDBTests/SingletonUserDefaultsTest.swift @@ -0,0 +1,174 @@ +import XCTest +import GRDB + +private struct AppConfiguration: Codable { + // Support for the single row guarantee + private var id = 1 + + // The stored properties + private var storedText: String? + // ... other properties + + // The public properties + var text: String { + get { storedText ?? "default" } + set { storedText = newValue } + } + + mutating func resetText() { + storedText = nil + } +} + +extension AppConfiguration { + /// The default configuration + static let `default` = AppConfiguration() +} + +// Database Access +extension AppConfiguration: FetchableRecord, PersistableRecord { + // Customize the default PersistableRecord behavior + func willUpdate(_ db: Database, columns: Set) 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 SingletonUserDefaultsTest: 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("storedText", .text) + // ... other columns + } + } + + func test_find_in_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_find_in_populated_database_null() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + try AppConfiguration().insert(db) + // When + let config = try AppConfiguration.find(db) + // Then + XCTAssertEqual(config.text, "default") + } + } + + func test_find_from_populated_database_not_null() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + try db.execute(sql: "INSERT INTO appConfiguration(storedText) VALUES ('initial')") + // When + let config = try AppConfiguration.find(db) + // Then + XCTAssertEqual(config.text, "initial") + } + } + + func test_save_in_empty_database() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + // When + var appConfiguration = try AppConfiguration.find(db) + appConfiguration.text = "test" + try appConfiguration.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, "storedText": "test"]) + } + } + + func test_save_in_populated_database() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + try db.execute(sql: "INSERT INTO appConfiguration(storedText) VALUES ('initial')") + // When + var appConfiguration = try AppConfiguration.find(db) + appConfiguration.text = "test" + try appConfiguration.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, "storedText": "test"]) + } + } + + func test_reset_and_save_in_populated_database() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + try db.execute(sql: "INSERT INTO appConfiguration(storedText) VALUES ('initial')") + // When + var appConfiguration = try AppConfiguration.find(db) + appConfiguration.resetText() + try appConfiguration.save(db) + // Then + try XCTAssertEqual(AppConfiguration.find(db).text, "default") + let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) + XCTAssertEqual(row, ["id": 1, "storedText": nil]) + } + } + + 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 + XCTAssertEqual(config.text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") + let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) + XCTAssertEqual(row, ["id": 1, "storedText": "test"]) + } + } + + func test_update_changes_in_populated_database() throws { + try makeDatabaseQueue().write { db in + // Given + try createEmptyAppConfigurationTable(db) + try db.execute(sql: "INSERT INTO appConfiguration(storedText) VALUES ('initial')") + // When + var config = try AppConfiguration.find(db) + try config.updateChanges(db) { + $0.text = "test" + } + // Then + XCTAssertEqual(config.text, "test") + try XCTAssertEqual(AppConfiguration.find(db).text, "test") + let row = try XCTUnwrap(Row.fetchOne(db, sql: "SELECT * FROM appConfiguration")) + XCTAssertEqual(row, ["id": 1, "storedText": "test"]) + } + } +}