add iOS
This commit is contained in:
+339
@@ -0,0 +1,339 @@
|
||||
import XCTest
|
||||
import GRDB
|
||||
|
||||
private struct Team: Codable, FetchableRecord, PersistableRecord {
|
||||
static let databaseTableName = "teams"
|
||||
var id: Int64
|
||||
var name: String
|
||||
}
|
||||
|
||||
private struct Player: Codable, FetchableRecord, PersistableRecord {
|
||||
static let databaseTableName = "players"
|
||||
static let teamScope = "team"
|
||||
static let team = Player.belongsTo(Team.self, key: teamScope)
|
||||
var id: Int64
|
||||
var teamId: Int64?
|
||||
var name: String
|
||||
}
|
||||
|
||||
private struct PlayerWithRequiredTeam: FetchableRecord {
|
||||
var player: Player
|
||||
var team: Team
|
||||
|
||||
init(row: Row) throws {
|
||||
player = try Player(row: row)
|
||||
team = row[Player.teamScope]
|
||||
}
|
||||
}
|
||||
|
||||
private struct PlayerWithOptionalTeam: FetchableRecord {
|
||||
var player: Player
|
||||
var team: Team?
|
||||
|
||||
init(row: Row) throws {
|
||||
player = try Player(row: row)
|
||||
team = row[Player.teamScope]
|
||||
}
|
||||
}
|
||||
|
||||
private struct PlayerWithTeamName: FetchableRecord {
|
||||
var player: Player
|
||||
var teamName: String?
|
||||
|
||||
init(row: Row) throws {
|
||||
player = try Player(row: row)
|
||||
teamName = row["teamName"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Test support for FetchableRecord records
|
||||
class AssociationBelongsToFetchableRecordTests: GRDBTestCase {
|
||||
|
||||
override func setup(_ dbWriter: some DatabaseWriter) throws {
|
||||
try dbWriter.write { db in
|
||||
try db.create(table: "teams") { t in
|
||||
t.primaryKey("id", .integer)
|
||||
t.column("name", .text)
|
||||
}
|
||||
try db.create(table: "players") { t in
|
||||
t.primaryKey("id", .integer)
|
||||
t.belongsTo("team")
|
||||
t.column("name", .text)
|
||||
}
|
||||
|
||||
try Team(id: 1, name: "Reds").insert(db)
|
||||
try Player(id: 1, teamId: 1, name: "Arthur").insert(db)
|
||||
try Player(id: 2, teamId: nil, name: "Barbara").insert(db)
|
||||
}
|
||||
}
|
||||
|
||||
func testIncludingRequired() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.including(required: Player.team)
|
||||
.asRequest(of: PlayerWithRequiredTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 1)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].team.id, 1)
|
||||
XCTAssertEqual(records[0].team.name, "Reds")
|
||||
}
|
||||
|
||||
func testAnnotatedWithRequired() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.annotated(withRequired: Player.team.select(Column("name").forKey("teamName")))
|
||||
.asRequest(of: PlayerWithTeamName.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 1)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].teamName, "Reds")
|
||||
}
|
||||
|
||||
func testIncludingOptional() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.including(optional: Player.team)
|
||||
.asRequest(of: PlayerWithOptionalTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 2)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].team!.id, 1)
|
||||
XCTAssertEqual(records[0].team!.name, "Reds")
|
||||
XCTAssertEqual(records[1].player.id, 2)
|
||||
XCTAssertNil(records[1].player.teamId)
|
||||
XCTAssertEqual(records[1].player.name, "Barbara")
|
||||
XCTAssertNil(records[1].team)
|
||||
}
|
||||
|
||||
func testAnnotatedWithOptional() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.annotated(withOptional: Player.team.select(Column("name").forKey("teamName")))
|
||||
.asRequest(of: PlayerWithTeamName.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 2)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].teamName, "Reds")
|
||||
XCTAssertEqual(records[1].player.id, 2)
|
||||
XCTAssertEqual(records[1].player.name, "Barbara")
|
||||
XCTAssertNil(records[1].teamName)
|
||||
}
|
||||
|
||||
func testJoiningRequired() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player.joining(required: Player.team)
|
||||
let players = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(players.count, 1)
|
||||
XCTAssertEqual(players[0].id, 1)
|
||||
XCTAssertEqual(players[0].teamId, 1)
|
||||
XCTAssertEqual(players[0].name, "Arthur")
|
||||
}
|
||||
|
||||
func testJoiningOptional() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player.joining(optional: Player.team)
|
||||
let players = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(players.count, 2)
|
||||
XCTAssertEqual(players[0].id, 1)
|
||||
XCTAssertEqual(players[0].teamId, 1)
|
||||
XCTAssertEqual(players[0].name, "Arthur")
|
||||
XCTAssertEqual(players[1].id, 2)
|
||||
XCTAssertNil(players[1].teamId)
|
||||
XCTAssertEqual(players[1].name, "Barbara")
|
||||
}
|
||||
|
||||
func testIncludingRequired_ColumnDecodingStrategy() throws {
|
||||
struct AnyKey: CodingKey {
|
||||
var stringValue: String
|
||||
var intValue: Int? { nil }
|
||||
init(stringValue: String) { self.stringValue = stringValue }
|
||||
init?(intValue: Int) { nil }
|
||||
}
|
||||
|
||||
struct XTeam: Decodable, FetchableRecord, TableRecord {
|
||||
static let databaseTableName = "teams"
|
||||
static let databaseColumnDecodingStrategy = DatabaseColumnDecodingStrategy.custom { column in
|
||||
AnyKey(stringValue: "x\(column)")
|
||||
}
|
||||
var xid: Int64
|
||||
var xname: String
|
||||
}
|
||||
|
||||
struct XPlayer: Decodable, FetchableRecord, TableRecord {
|
||||
static let databaseTableName = "players"
|
||||
static let databaseColumnDecodingStrategy = DatabaseColumnDecodingStrategy.custom { column in
|
||||
AnyKey(stringValue: "x\(column)")
|
||||
}
|
||||
static let team = belongsTo(Team.self, key: "team")
|
||||
static let xteam = belongsTo(XTeam.self, key: "xteam")
|
||||
var xid: Int64
|
||||
var xteamId: Int64?
|
||||
var xname: String
|
||||
}
|
||||
|
||||
do {
|
||||
struct XPlayerWithRequiredXTeam: Decodable, FetchableRecord {
|
||||
var xplayer: XPlayer
|
||||
var xteam: XTeam
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = XPlayer
|
||||
.including(required: XPlayer.xteam)
|
||||
.asRequest(of: XPlayerWithRequiredXTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xid, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xteamId, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xname, "Arthur")
|
||||
XCTAssertEqual(records[0].xteam.xid, 1)
|
||||
XCTAssertEqual(records[0].xteam.xname, "Reds")
|
||||
}
|
||||
|
||||
do {
|
||||
struct XPlayerWithRequiredTeam: Decodable, FetchableRecord {
|
||||
var xplayer: XPlayer
|
||||
var team: Team
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = XPlayer
|
||||
.including(required: XPlayer.team)
|
||||
.asRequest(of: XPlayerWithRequiredTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xid, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xteamId, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xname, "Arthur")
|
||||
XCTAssertEqual(records[0].team.id, 1)
|
||||
XCTAssertEqual(records[0].team.name, "Reds")
|
||||
}
|
||||
|
||||
do {
|
||||
struct PlayerWithRequiredXTeam: Decodable, FetchableRecord {
|
||||
var player: Player
|
||||
var xteam: XTeam
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.including(required: Player.belongsTo(XTeam.self, key: "xteam"))
|
||||
.asRequest(of: PlayerWithRequiredXTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 1)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].xteam.xid, 1)
|
||||
XCTAssertEqual(records[0].xteam.xname, "Reds")
|
||||
}
|
||||
}
|
||||
|
||||
func testIncludingOptional_ColumnDecodingStrategy() throws {
|
||||
struct AnyKey: CodingKey {
|
||||
var stringValue: String
|
||||
var intValue: Int? { nil }
|
||||
init(stringValue: String) { self.stringValue = stringValue }
|
||||
init?(intValue: Int) { nil }
|
||||
}
|
||||
|
||||
struct XTeam: Decodable, FetchableRecord, TableRecord {
|
||||
static let databaseTableName = "teams"
|
||||
static let databaseColumnDecodingStrategy = DatabaseColumnDecodingStrategy.custom { column in
|
||||
AnyKey(stringValue: "x\(column)")
|
||||
}
|
||||
var xid: Int64
|
||||
var xname: String
|
||||
}
|
||||
|
||||
struct XPlayer: Decodable, FetchableRecord, TableRecord {
|
||||
static let databaseTableName = "players"
|
||||
static let databaseColumnDecodingStrategy = DatabaseColumnDecodingStrategy.custom { column in
|
||||
AnyKey(stringValue: "x\(column)")
|
||||
}
|
||||
static let team = belongsTo(Team.self, key: "team")
|
||||
static let xteam = belongsTo(XTeam.self, key: "xteam")
|
||||
var xid: Int64
|
||||
var xteamId: Int64?
|
||||
var xname: String
|
||||
}
|
||||
|
||||
do {
|
||||
struct XPlayerWithOptionalXTeam: Decodable, FetchableRecord {
|
||||
var xplayer: XPlayer
|
||||
var xteam: XTeam?
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = XPlayer
|
||||
.including(optional: XPlayer.xteam)
|
||||
.asRequest(of: XPlayerWithOptionalXTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 2)
|
||||
XCTAssertEqual(records[0].xplayer.xid, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xteamId, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xname, "Arthur")
|
||||
XCTAssertEqual(records[0].xteam!.xid, 1)
|
||||
XCTAssertEqual(records[0].xteam!.xname, "Reds")
|
||||
XCTAssertEqual(records[1].xplayer.xid, 2)
|
||||
XCTAssertNil(records[1].xplayer.xteamId)
|
||||
XCTAssertEqual(records[1].xplayer.xname, "Barbara")
|
||||
XCTAssertNil(records[1].xteam)
|
||||
}
|
||||
|
||||
do {
|
||||
struct XPlayerWithOptionalTeam: Decodable, FetchableRecord {
|
||||
var xplayer: XPlayer
|
||||
var team: Team?
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = XPlayer
|
||||
.including(optional: XPlayer.team)
|
||||
.asRequest(of: XPlayerWithOptionalTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 2)
|
||||
XCTAssertEqual(records[0].xplayer.xid, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xteamId, 1)
|
||||
XCTAssertEqual(records[0].xplayer.xname, "Arthur")
|
||||
XCTAssertEqual(records[0].team!.id, 1)
|
||||
XCTAssertEqual(records[0].team!.name, "Reds")
|
||||
XCTAssertEqual(records[1].xplayer.xid, 2)
|
||||
XCTAssertNil(records[1].xplayer.xteamId)
|
||||
XCTAssertEqual(records[1].xplayer.xname, "Barbara")
|
||||
XCTAssertNil(records[1].team)
|
||||
}
|
||||
|
||||
do {
|
||||
struct PlayerWithOptionalXTeam: Decodable, FetchableRecord {
|
||||
var player: Player
|
||||
var xteam: XTeam?
|
||||
}
|
||||
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
let request = Player
|
||||
.including(optional: Player.belongsTo(XTeam.self, key: "xteam"))
|
||||
.asRequest(of: PlayerWithOptionalXTeam.self)
|
||||
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
|
||||
XCTAssertEqual(records.count, 2)
|
||||
XCTAssertEqual(records[0].player.id, 1)
|
||||
XCTAssertEqual(records[0].player.teamId, 1)
|
||||
XCTAssertEqual(records[0].player.name, "Arthur")
|
||||
XCTAssertEqual(records[0].xteam!.xid, 1)
|
||||
XCTAssertEqual(records[0].xteam!.xname, "Reds")
|
||||
XCTAssertEqual(records[1].player.id, 2)
|
||||
XCTAssertNil(records[1].player.teamId)
|
||||
XCTAssertEqual(records[1].player.name, "Barbara")
|
||||
XCTAssertNil(records[1].xteam)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user