Skip to content

Commit 78eb204

Browse files
committed
Updated unit tests
1 parent 40e4a9f commit 78eb204

2 files changed

Lines changed: 250 additions & 2 deletions

File tree

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,48 @@
11
import Foundation
22
import XCTest
3-
import CoreModel
3+
import NIO
44
@testable import MongoDBModel
55

66
final class MongoDBModelTests: XCTestCase {
77

8-
func testExample() throws {
8+
func testMongoDB() async throws {
99

10+
let elg = MultiThreadedEventLoopGroup(numberOfThreads: 4)
11+
let client = try MongoClient("mongodb://localhost:27017", using: elg)
12+
let database = client.db("test")
13+
14+
defer {
15+
// clean up driver resources
16+
try? client.syncClose()
17+
cleanupMongoSwift()
18+
19+
// shut down EventLoopGroup
20+
try? elg.syncShutdownGracefully()
21+
}
22+
23+
let model = Model(entities: Person.self, Event.self)
24+
let store = MongoModelStorage(
25+
database: database,
26+
model: model
27+
)
28+
29+
var person1 = Person(
30+
name: "John Appleseed",
31+
age: 22
32+
)
33+
34+
try await store.insert(person1)
35+
36+
var event1 = Event(
37+
name: "WWDC",
38+
date: Date(timeIntervalSinceNow: 60 * 60 * 24 * 10),
39+
people: [person1.id]
40+
)
41+
42+
try await store.insert(event1)
43+
person1 = try await store.fetch(Person.self, for: person1.id)!
44+
XCTAssertEqual(person1.events, [event1.id])
45+
event1 = try await store.fetch(Event.self, for: event1.id)!
46+
XCTAssertEqual(event1.people, [person1.id])
1047
}
1148
}
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
//
2+
// TestModel.swift
3+
//
4+
//
5+
// Created by Alsey Coleman Miller on 8/17/23.
6+
//
7+
8+
import Foundation
9+
import CoreModel
10+
11+
struct Person: Equatable, Hashable, Codable, Identifiable {
12+
13+
let id: UUID
14+
15+
var name: String
16+
17+
var created: Date
18+
19+
var age: UInt
20+
21+
var events: [Event.ID]
22+
23+
init(
24+
id: UUID = UUID(),
25+
name: String,
26+
created: Date = Date(),
27+
age: UInt,
28+
events: [Event.ID] = []
29+
) {
30+
self.id = id
31+
self.name = name
32+
self.created = created
33+
self.age = age
34+
self.events = events
35+
}
36+
37+
enum CodingKeys: CodingKey {
38+
case id
39+
case name
40+
case created
41+
case age
42+
case events
43+
}
44+
45+
init(from decoder: Decoder) throws {
46+
let container: KeyedDecodingContainer<Person.CodingKeys> = try decoder.container(keyedBy: Person.CodingKeys.self)
47+
48+
self.id = try container.decode(UUID.self, forKey: Person.CodingKeys.id)
49+
self.name = try container.decode(String.self, forKey: Person.CodingKeys.name)
50+
self.created = try container.decode(Date.self, forKey: Person.CodingKeys.created)
51+
self.age = try container.decode(UInt.self, forKey: Person.CodingKeys.age)
52+
self.events = try container.decode([Event.ID].self, forKey: Person.CodingKeys.events)
53+
54+
}
55+
56+
func encode(to encoder: Encoder) throws {
57+
var container = encoder.container(keyedBy: Person.CodingKeys.self)
58+
59+
try container.encode(self.id, forKey: Person.CodingKeys.id)
60+
try container.encode(self.name, forKey: Person.CodingKeys.name)
61+
try container.encode(self.created, forKey: Person.CodingKeys.created)
62+
try container.encode(self.age, forKey: Person.CodingKeys.age)
63+
try container.encode(self.events, forKey: Person.CodingKeys.events)
64+
}
65+
}
66+
67+
extension Person: Entity {
68+
69+
public static var entityName: EntityName { "Person" }
70+
71+
static var attributes: [CodingKeys: AttributeType] {
72+
[
73+
.name: .string,
74+
.created: .date,
75+
.age: .int16
76+
]
77+
}
78+
79+
static var relationships: [CodingKeys: Relationship] {
80+
[
81+
.events: .init(
82+
id: PropertyKey(CodingKeys.events),
83+
type: .toMany,
84+
destinationEntity: Event.entityName,
85+
inverseRelationship: PropertyKey(Event.CodingKeys.people)
86+
)
87+
]
88+
}
89+
90+
init(from container: ModelData) throws {
91+
guard container.entity == Self.entityName else {
92+
throw DecodingError.typeMismatch(Self.self, DecodingError.Context(codingPath: [], debugDescription: "Cannot decode \(String(describing: Self.self)) from \(container.entity)"))
93+
}
94+
guard let id = UUID(uuidString: container.id.rawValue) else {
95+
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "Cannot decode identifier from \(container.id)"))
96+
}
97+
self.id = id
98+
self.name = try container.decode(String.self, forKey: Person.CodingKeys.name)
99+
self.created = try container.decode(Date.self, forKey: Person.CodingKeys.created)
100+
self.age = try container.decode(UInt.self, forKey: Person.CodingKeys.age)
101+
self.events = try container.decodeRelationship([Event.ID].self, forKey: Person.CodingKeys.events)
102+
}
103+
104+
func encode() -> ModelData {
105+
106+
var container = ModelData(
107+
entity: Self.entityName,
108+
id: ObjectID(rawValue: self.id.description)
109+
)
110+
container.encode(self.name, forKey: Person.CodingKeys.name)
111+
container.encode(self.created, forKey: Person.CodingKeys.created)
112+
container.encode(self.age, forKey: Person.CodingKeys.age)
113+
container.encodeRelationship(self.events, forKey: Person.CodingKeys.events)
114+
return container
115+
}
116+
}
117+
118+
struct Event: Equatable, Hashable, Codable, Identifiable {
119+
120+
let id: UUID
121+
122+
var name: String
123+
124+
var date: Date
125+
126+
var people: [Person.ID]
127+
128+
//var speaker: Person.ID?
129+
130+
//var notes: String?
131+
132+
init(id: UUID = UUID(), name: String, date: Date, people: [Person.ID] = []) {
133+
self.id = id
134+
self.name = name
135+
self.date = date
136+
self.people = people
137+
}
138+
139+
enum CodingKeys: CodingKey {
140+
case id
141+
case name
142+
case date
143+
case people
144+
}
145+
146+
init(from decoder: Decoder) throws {
147+
let container: KeyedDecodingContainer<Event.CodingKeys> = try decoder.container(keyedBy: Event.CodingKeys.self)
148+
149+
self.id = try container.decode(UUID.self, forKey: Event.CodingKeys.id)
150+
self.name = try container.decode(String.self, forKey: Event.CodingKeys.name)
151+
self.date = try container.decode(Date.self, forKey: Event.CodingKeys.date)
152+
self.people = try container.decode([Person.ID].self, forKey: Event.CodingKeys.people)
153+
154+
}
155+
156+
func encode(to encoder: Encoder) throws {
157+
var container = encoder.container(keyedBy: Event.CodingKeys.self)
158+
159+
try container.encode(self.id, forKey: Event.CodingKeys.id)
160+
try container.encode(self.name, forKey: Event.CodingKeys.name)
161+
try container.encode(self.date, forKey: Event.CodingKeys.date)
162+
try container.encode(self.people, forKey: Event.CodingKeys.people)
163+
}
164+
}
165+
166+
extension Event: Entity {
167+
168+
public static var entityName: EntityName { "Event" }
169+
170+
static var attributes: [CodingKeys: AttributeType] {
171+
[
172+
.name: .string,
173+
.date: .date
174+
]
175+
}
176+
177+
static var relationships: [CodingKeys: Relationship] {
178+
[
179+
.people: .init(
180+
id: PropertyKey(CodingKeys.people),
181+
type: .toMany,
182+
destinationEntity: Person.entityName,
183+
inverseRelationship: PropertyKey(Person.CodingKeys.events))
184+
]
185+
}
186+
187+
init(from container: ModelData) throws {
188+
guard container.entity == Self.entityName else {
189+
throw DecodingError.typeMismatch(Self.self, DecodingError.Context(codingPath: [], debugDescription: "Cannot decode \(String(describing: Self.self)) from \(container.entity)"))
190+
}
191+
guard let id = UUID(uuidString: container.id.rawValue) else {
192+
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "Cannot decode identifier from \(container.id)"))
193+
}
194+
self.id = id
195+
self.name = try container.decode(String.self, forKey: Event.CodingKeys.name)
196+
self.date = try container.decode(Date.self, forKey: Event.CodingKeys.date)
197+
self.people = try container.decodeRelationship([Person.ID].self, forKey: Event.CodingKeys.people)
198+
}
199+
200+
func encode() -> ModelData {
201+
202+
var container = ModelData(
203+
entity: Self.entityName,
204+
id: ObjectID(rawValue: self.id.description)
205+
)
206+
container.encode(self.name, forKey: Event.CodingKeys.name)
207+
container.encode(self.date, forKey: Event.CodingKeys.date)
208+
container.encodeRelationship(self.people, forKey: Event.CodingKeys.people)
209+
return container
210+
}
211+
}

0 commit comments

Comments
 (0)