Skip to content

Commit ef5f33a

Browse files
committed
Updated unit tests
1 parent 854bed1 commit ef5f33a

2 files changed

Lines changed: 361 additions & 1 deletion

File tree

Tests/CoreModelMongoDBTests/MongoDBModelTests.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Foundation
22
import XCTest
33
import NIO
4+
@testable import CoreModel
45
@testable import MongoDBModel
56

67
final class MongoDBModelTests: XCTestCase {
@@ -20,7 +21,7 @@ final class MongoDBModelTests: XCTestCase {
2021
try? elg.syncShutdownGracefully()
2122
}
2223

23-
let model = Model(entities: Person.self, Event.self)
24+
let model = Model(entities: Person.self, Event.self, Campground.self, Campground.RentalUnit.self)
2425
let store = MongoModelStorage(
2526
database: database,
2627
model: model
@@ -36,6 +37,7 @@ final class MongoDBModelTests: XCTestCase {
3637
date: Date(timeIntervalSinceNow: 60 * 60 * 24 * 10)
3738
)
3839

40+
// set relationship
3941
event1.people.append(person1.id)
4042
person1.events.append(event1.id)
4143

@@ -45,5 +47,40 @@ final class MongoDBModelTests: XCTestCase {
4547
XCTAssertEqual(person1.events, [event1.id])
4648
event1 = try await store.fetch(Event.self, for: event1.id)!
4749
XCTAssertEqual(event1.people, [person1.id])
50+
51+
var campground = Campground(
52+
name: "Fair Play RV Park",
53+
address: """
54+
243 Fisher Cove Rd,
55+
Fair Play, SC
56+
""",
57+
location: .init(latitude: 34.51446212994721, longitude: -83.01371101951648),
58+
descriptionText: """
59+
At Fair Play RV Park, we are committed to providing a clean, safe and fun environment for all of our guests, including your fur-babies! We look forward to meeting you and having you stay with us!
60+
""",
61+
officeHours: Campground.Schedule(start: 60 * 8, end: 60 * 18)
62+
)
63+
64+
let rentalUnit = Campground.RentalUnit(
65+
campground: campground.id,
66+
name: "A1",
67+
amenities: [.amp50, .water, .mail, .river, .laundry],
68+
checkout: campground.officeHours
69+
)
70+
71+
// set relationship
72+
campground.units = [rentalUnit.id]
73+
74+
var campgroundData = try campground.encode(log: { print("Encoder:", $0) })
75+
try await store.insert(campgroundData)
76+
let rentalUnitData = try rentalUnit.encode(log: { print("Encoder:", $0) })
77+
XCTAssertEqual(rentalUnitData.relationships[PropertyKey(Campground.RentalUnit.CodingKeys.campground)], .toOne(ObjectID(campground.id)))
78+
try await store.insert(rentalUnitData)
79+
campgroundData = try await store.fetch(Campground.entityName, for: ObjectID(campground.id))!
80+
campground = try .init(from: campgroundData, log: { print("Decoder:", $0) })
81+
XCTAssertEqual(campground.units, [rentalUnit.id])
82+
XCTAssertEqual(campgroundData.relationships[PropertyKey(Campground.CodingKeys.units)], .toMany([ObjectID(rentalUnit.id)]))
83+
let fetchedRentalUnit = try await store.fetch(Campground.RentalUnit.self, for: rentalUnit.id)
84+
XCTAssertEqual(fetchedRentalUnit, rentalUnit)
4885
}
4986
}

Tests/CoreModelMongoDBTests/TestModel.swift

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,326 @@ extension Event: Entity {
157157
]
158158
}
159159
}
160+
161+
/// Campground Location
162+
public struct Campground: Equatable, Hashable, Codable, Identifiable {
163+
164+
public let id: UUID
165+
166+
public let created: Date
167+
168+
public let updated: Date
169+
170+
public var name: String
171+
172+
public var address: String
173+
174+
public var location: LocationCoordinates
175+
176+
public var amenities: [Amenity]
177+
178+
public var phoneNumber: String?
179+
180+
public var descriptionText: String
181+
182+
/// The number of seconds from GMT.
183+
public var timeZone: Int
184+
185+
public var notes: String?
186+
187+
public var directions: String?
188+
189+
public var units: [RentalUnit.ID]
190+
191+
public var officeHours: Schedule
192+
193+
public init(
194+
id: UUID = UUID(),
195+
created: Date = Date(),
196+
updated: Date = Date(),
197+
name: String,
198+
address: String,
199+
location: LocationCoordinates,
200+
amenities: [Amenity] = [],
201+
phoneNumber: String? = nil,
202+
descriptionText: String,
203+
notes: String? = nil,
204+
directions: String? = nil,
205+
units: [RentalUnit.ID] = [],
206+
timeZone: Int = 0,
207+
officeHours: Schedule
208+
) {
209+
self.id = id
210+
self.created = created
211+
self.updated = updated
212+
self.name = name
213+
self.address = address
214+
self.location = location
215+
self.amenities = amenities
216+
self.phoneNumber = phoneNumber
217+
self.descriptionText = descriptionText
218+
self.notes = notes
219+
self.directions = directions
220+
self.units = units
221+
self.timeZone = timeZone
222+
self.officeHours = officeHours
223+
}
224+
225+
public enum CodingKeys: CodingKey {
226+
case id
227+
case created
228+
case updated
229+
case name
230+
case address
231+
case location
232+
case amenities
233+
case phoneNumber
234+
case descriptionText
235+
case timeZone
236+
case notes
237+
case directions
238+
case units
239+
case officeHours
240+
}
241+
}
242+
243+
extension Campground: Entity {
244+
245+
public static var entityName: EntityName { "Campground" }
246+
247+
public static var attributes: [CodingKeys: AttributeType] {
248+
[
249+
.name : .string,
250+
.created : .date,
251+
.updated : .date,
252+
.address : .string,
253+
.location: .string,
254+
.amenities: .string,
255+
.phoneNumber: .string,
256+
.descriptionText: .string,
257+
.timeZone: .int32,
258+
.notes: .string,
259+
.directions: .string,
260+
.officeHours: .string
261+
]
262+
}
263+
264+
public static var relationships: [CodingKeys: Relationship] {
265+
[
266+
.units : Relationship(
267+
id: PropertyKey(CodingKeys.units),
268+
type: .toMany,
269+
destinationEntity: RentalUnit.entityName,
270+
inverseRelationship: PropertyKey(RentalUnit.CodingKeys.campground)
271+
)
272+
]
273+
}
274+
}
275+
276+
public extension Campground {
277+
278+
/// Campground Amenities
279+
enum Amenity: String, Codable, CaseIterable {
280+
281+
case water
282+
case amp30
283+
case amp50
284+
case wifi
285+
case laundry
286+
case mail
287+
case dumpStation
288+
case picnicArea
289+
case storage
290+
case cabins
291+
case showers
292+
case restrooms
293+
case pool
294+
case fishing
295+
case beach
296+
case lake
297+
case river
298+
case rv
299+
case tent
300+
case pets
301+
}
302+
}
303+
304+
extension Array: AttributeEncodable where Self.Element == Campground.Amenity {
305+
306+
public var attributeValue: AttributeValue {
307+
let string = self.reduce("", { $0 + ($0.isEmpty ? "" : ",") + $1.rawValue })
308+
return .string(string)
309+
}
310+
}
311+
312+
extension Array: AttributeDecodable where Self.Element == Campground.Amenity {
313+
314+
public init?(attributeValue: AttributeValue) {
315+
guard let string = String(attributeValue: attributeValue) else {
316+
return nil
317+
}
318+
let components = string
319+
.components(separatedBy: ",")
320+
.filter { $0.isEmpty == false }
321+
var values = [Campground.Amenity]()
322+
values.reserveCapacity(components.count)
323+
for element in components {
324+
guard let value = Self.Element(rawValue: element) else {
325+
return nil
326+
}
327+
values.append(value)
328+
}
329+
self = values
330+
}
331+
}
332+
333+
public extension Campground {
334+
335+
/// Location Coordinates
336+
struct LocationCoordinates: Equatable, Hashable, Codable {
337+
338+
/// Latitude
339+
public var latitude: Double
340+
341+
/// Longitude
342+
public var longitude: Double
343+
344+
public init(latitude: Double, longitude: Double) {
345+
self.latitude = latitude
346+
self.longitude = longitude
347+
}
348+
}
349+
}
350+
351+
extension Campground.LocationCoordinates: AttributeEncodable {
352+
353+
public var attributeValue: AttributeValue {
354+
return .string("\(latitude),\(longitude)")
355+
}
356+
}
357+
358+
extension Campground.LocationCoordinates: AttributeDecodable {
359+
360+
public init?(attributeValue: AttributeValue) {
361+
guard let string = String(attributeValue: attributeValue) else {
362+
return nil
363+
}
364+
let components = string.components(separatedBy: ",")
365+
guard components.count == 2,
366+
let latitude = Double(components[0]),
367+
let longitude = Double(components[1]) else {
368+
return nil
369+
}
370+
self.init(latitude: latitude, longitude: longitude)
371+
}
372+
}
373+
374+
public extension Campground {
375+
376+
/// Schedule (e.g. Check in, Check Out)
377+
struct Schedule: Equatable, Hashable, Codable {
378+
379+
public var start: UInt
380+
381+
public var end: UInt
382+
383+
public init(start: UInt, end: UInt) {
384+
assert(start < end)
385+
self.start = start
386+
self.end = end
387+
}
388+
}
389+
}
390+
391+
extension Campground.Schedule: AttributeEncodable {
392+
393+
public var attributeValue: AttributeValue {
394+
return .string("\(start),\(end)")
395+
}
396+
}
397+
398+
extension Campground.Schedule: AttributeDecodable {
399+
400+
public init?(attributeValue: AttributeValue) {
401+
guard let string = String(attributeValue: attributeValue) else {
402+
return nil
403+
}
404+
let components = string.components(separatedBy: ",")
405+
guard components.count == 2,
406+
let start = UInt(components[0]),
407+
let end = UInt(components[1]) else {
408+
return nil
409+
}
410+
self.init(start: start, end: end)
411+
}
412+
}
413+
414+
public extension Campground {
415+
416+
/// Campground Rental Unit
417+
struct RentalUnit: Equatable, Hashable, Codable, Identifiable {
418+
419+
public let id: UUID
420+
421+
public let campground: Campground.ID
422+
423+
public var name: String
424+
425+
public var notes: String?
426+
427+
public var amenities: [Amenity]
428+
429+
public var checkout: Schedule
430+
431+
public init(
432+
id: UUID = UUID(),
433+
campground: Campground.ID,
434+
name: String,
435+
notes: String? = nil,
436+
amenities: [Amenity] = [],
437+
checkout: Schedule
438+
) {
439+
self.id = id
440+
self.campground = campground
441+
self.name = name
442+
self.notes = notes
443+
self.amenities = amenities
444+
self.checkout = checkout
445+
}
446+
447+
public enum CodingKeys: CodingKey {
448+
449+
case id
450+
case campground
451+
case name
452+
case notes
453+
case amenities
454+
case checkout
455+
}
456+
}
457+
}
458+
459+
extension Campground.RentalUnit: Entity {
460+
461+
public static var entityName: EntityName { "RentalUnit" }
462+
463+
public static var attributes: [CodingKeys: AttributeType] {
464+
[
465+
.name : .string,
466+
.notes : .string,
467+
.amenities : .string,
468+
.checkout : .string
469+
]
470+
}
471+
472+
public static var relationships: [CodingKeys: Relationship] {
473+
[
474+
.campground : Relationship(
475+
id: PropertyKey(CodingKeys.campground),
476+
type: .toOne,
477+
destinationEntity: Campground.entityName,
478+
inverseRelationship: PropertyKey(Campground.CodingKeys.units)
479+
)
480+
]
481+
}
482+
}

0 commit comments

Comments
 (0)