Skip to content

Commit b9bac17

Browse files
committed
Issue #5, moved MockDataService to a separate file and added some documentation.
1 parent 4b598bb commit b9bac17

File tree

4 files changed

+161
-142
lines changed

4 files changed

+161
-142
lines changed

SwapiSwift.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
8F535D7F23BF70DC00E72BF9 /* StarshipGraphService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F535D7E23BF70DC00E72BF9 /* StarshipGraphService.swift */; };
3333
8F535D8123BF724700E72BF9 /* VehicleGraphService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F535D8023BF724700E72BF9 /* VehicleGraphService.swift */; };
3434
8F6EA6AE23C53ABA0079491D /* MockGraphDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F6EA6AD23C53ABA0079491D /* MockGraphDataService.swift */; };
35+
8F6EA6B023C53C750079491D /* MockDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F6EA6AF23C53C750079491D /* MockDataService.swift */; };
3536
8FBF743923BE6D07008FF80D /* FilmGraphService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FBF743823BE6D07008FF80D /* FilmGraphService.swift */; };
3637
8FBF743B23BE6D66008FF80D /* GraphService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FBF743A23BE6D66008FF80D /* GraphService.swift */; };
3738
8FE79E4723BBF4CC00897C77 /* VehicleModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE79E4623BBF4CC00897C77 /* VehicleModelTests.swift */; };
@@ -89,6 +90,7 @@
8990
8F535D7E23BF70DC00E72BF9 /* StarshipGraphService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarshipGraphService.swift; sourceTree = "<group>"; };
9091
8F535D8023BF724700E72BF9 /* VehicleGraphService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleGraphService.swift; sourceTree = "<group>"; };
9192
8F6EA6AD23C53ABA0079491D /* MockGraphDataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockGraphDataService.swift; sourceTree = "<group>"; };
93+
8F6EA6AF23C53C750079491D /* MockDataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDataService.swift; sourceTree = "<group>"; };
9294
8FBF743823BE6D07008FF80D /* FilmGraphService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilmGraphService.swift; sourceTree = "<group>"; };
9395
8FBF743A23BE6D66008FF80D /* GraphService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphService.swift; sourceTree = "<group>"; };
9496
8FE79E4623BBF4CC00897C77 /* VehicleModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleModelTests.swift; sourceTree = "<group>"; };
@@ -218,6 +220,7 @@
218220
isa = PBXGroup;
219221
children = (
220222
8FE79E5A23BD02C900897C77 /* SwapiService.swift */,
223+
8F6EA6AF23C53C750079491D /* MockDataService.swift */,
221224
8F6EA6AD23C53ABA0079491D /* MockGraphDataService.swift */,
222225
8FBF743823BE6D07008FF80D /* FilmGraphService.swift */,
223226
8F535D7823BF65F300E72BF9 /* PersonGraphService.swift */,
@@ -382,6 +385,7 @@
382385
8FBF743923BE6D07008FF80D /* FilmGraphService.swift in Sources */,
383386
8F6EA6AE23C53ABA0079491D /* MockGraphDataService.swift in Sources */,
384387
8FE79E6623BD25E800897C77 /* Parsing.swift in Sources */,
388+
8F6EA6B023C53C750079491D /* MockDataService.swift in Sources */,
385389
8F34E27523BB85ED00608F46 /* Vehicle.swift in Sources */,
386390
8FE79E5B23BD02C900897C77 /* SwapiService.swift in Sources */,
387391
8F34E26F23BB81D500608F46 /* Species.swift in Sources */,
+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//
2+
// MockDataService.swift
3+
// SwapiSwift
4+
//
5+
// Created by Joe Bramhall on 1/7/20.
6+
// Copyright © 2020 thinx. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import Combine
11+
12+
/// A simple mock data service conforming to `SwapiService` initialized with a resource conforming to `SwapiResource`.
13+
/// Designed for use in testing and SwiftUI development.
14+
public struct MockDataService<T: SwapiResource>: SwapiService {
15+
16+
let mockData: T
17+
18+
/// Intializes a new instance of `MockDataService` with a specified resource.
19+
/// - Parameter mockData: The specified resource conforming to `SwapiResource` that will be returned by the mock data service.
20+
public init(mockData: T) {
21+
self.mockData = mockData
22+
}
23+
24+
public func film(withId resourceId: String) -> AnyPublisher<Film, ServiceError> {
25+
guard let filmData = mockData as? Film else {
26+
fatalError("Expected mock data to be initialized with type Film")
27+
}
28+
return Result.Publisher(filmData).eraseToAnyPublisher()
29+
}
30+
31+
public func person(withId resourceId: String) -> AnyPublisher<Person, ServiceError> {
32+
guard let personData = mockData as? Person else {
33+
fatalError("Expected mock data to be initialized with type Person")
34+
}
35+
return Result.Publisher(personData).eraseToAnyPublisher()
36+
}
37+
38+
public func planet(withId resourceId: String) -> AnyPublisher<Planet, ServiceError> {
39+
guard let planetData = mockData as? Planet else {
40+
fatalError("Expected mock data to be initialized with type Planet")
41+
}
42+
return Result.Publisher(planetData).eraseToAnyPublisher()
43+
}
44+
45+
public func planet(withResourceUrl url: String?) -> AnyPublisher<Planet, ServiceError> {
46+
guard let planetData = mockData as? Planet else {
47+
fatalError("Expected mock data to be initialized with type Planet")
48+
}
49+
return Result.Publisher(planetData).eraseToAnyPublisher()
50+
}
51+
52+
public func species(withId resourceId: String) -> AnyPublisher<Species, ServiceError> {
53+
guard let speciesData = mockData as? Species else {
54+
fatalError("Expected mock data to be initialized with type Species")
55+
}
56+
return Result.Publisher(speciesData).eraseToAnyPublisher()
57+
}
58+
59+
public func starship(withId resourceId: String) -> AnyPublisher<Starship, ServiceError> {
60+
guard let starshipData = mockData as? Starship else {
61+
fatalError("Expected mock data to be initialized with type Starship")
62+
}
63+
return Result.Publisher(starshipData).eraseToAnyPublisher()
64+
}
65+
66+
public func vehicle(withId resourceId: String) -> AnyPublisher<Vehicle, ServiceError> {
67+
guard let vehicleData = mockData as? Vehicle else {
68+
fatalError("Expected mock data to be initialized with type Vehicle")
69+
}
70+
return Result.Publisher(vehicleData).eraseToAnyPublisher()
71+
}
72+
73+
public func allFilms(page: String?) -> AnyPublisher<ResourceRoot<Film>, ServiceError> {
74+
guard let filmsData = mockData as? ResourceRoot<Film> else {
75+
fatalError("Expected mock data to be initialized with type FilmResourceRoot")
76+
}
77+
return Result.Publisher(filmsData).eraseToAnyPublisher()
78+
}
79+
80+
public func allPeople(page: String?) -> AnyPublisher<ResourceRoot<Person>, ServiceError> {
81+
guard let peopleData = mockData as? ResourceRoot<Person> else {
82+
fatalError("Expected mock data to be initialzed with type PersonResourceRoot")
83+
}
84+
return Result.Publisher(peopleData).eraseToAnyPublisher()
85+
}
86+
87+
public func allPlanets(page: String?) -> AnyPublisher<ResourceRoot<Planet>, ServiceError> {
88+
guard let planetsData = mockData as? ResourceRoot<Planet> else {
89+
fatalError("Expected mock data to be initialzed with type PlanetResourceRoot")
90+
}
91+
return Result.Publisher(planetsData).eraseToAnyPublisher()
92+
}
93+
94+
public func allSpecies(page: String?) -> AnyPublisher<ResourceRoot<Species>, ServiceError> {
95+
guard let speciesData = mockData as? ResourceRoot<Species> else {
96+
fatalError("Expected mock data to be initialzed with type SpeciesResourceRoot")
97+
}
98+
return Result.Publisher(speciesData).eraseToAnyPublisher()
99+
}
100+
101+
public func allStarships(page: String?) -> AnyPublisher<ResourceRoot<Starship>, ServiceError> {
102+
guard let starshipsData = mockData as? ResourceRoot<Starship> else {
103+
fatalError("Expected mock data to be initialzed with type StarshipResourceRoot")
104+
}
105+
return Result.Publisher(starshipsData).eraseToAnyPublisher()
106+
}
107+
108+
public func allVehicles(page: String?) -> AnyPublisher<ResourceRoot<Vehicle>, ServiceError> {
109+
guard let vehiclesData = mockData as? ResourceRoot<Vehicle> else {
110+
fatalError("Expected mock data to be initialzed with type VehicleResourceRoot")
111+
}
112+
return Result.Publisher(vehiclesData).eraseToAnyPublisher()
113+
}
114+
115+
public func people(fromResourceUrls urls: [String]) -> AnyPublisher<[Person], ServiceError> {
116+
guard let people = mockData as? [Person] else {
117+
fatalError("Expected mock data to be initialized with type Person array")
118+
}
119+
return Result.Publisher(people).eraseToAnyPublisher()
120+
}
121+
122+
public func starships(fromResourceUrls urls: [String]) -> AnyPublisher<[Starship], ServiceError> {
123+
guard let starships = mockData as? [Starship] else {
124+
fatalError("Expected mock data to be initialized with type Starship array")
125+
}
126+
return Result.Publisher(starships).eraseToAnyPublisher()
127+
}
128+
129+
public func planets(fromResourceUrls urls: [String]) -> AnyPublisher<[Planet], ServiceError> {
130+
guard let planets = mockData as? [Planet] else {
131+
fatalError("Expected mock data to be initialized with type Planet array")
132+
}
133+
return Result.Publisher(planets).eraseToAnyPublisher()
134+
}
135+
136+
public func species(fromResourceUrls urls: [String]) -> AnyPublisher<[Species], ServiceError> {
137+
guard let species = mockData as? [Species] else {
138+
fatalError("Expected mock data to be initialized with type Species array")
139+
}
140+
return Result.Publisher(species).eraseToAnyPublisher()
141+
}
142+
143+
public func vehicles(fromResourceUrls urls: [String]) -> AnyPublisher<[Vehicle], ServiceError> {
144+
guard let vehicles = mockData as? [Vehicle] else {
145+
fatalError("Expected mock data to be initialized with type Vehicle array")
146+
}
147+
return Result.Publisher(vehicles).eraseToAnyPublisher()
148+
}
149+
150+
public func films(fromResourceUrls urls: [String]) -> AnyPublisher<[Film], ServiceError> {
151+
guard let films = mockData as? [Film] else {
152+
fatalError("Expected mock data to be initialized with type Film array")
153+
}
154+
return Result.Publisher(films).eraseToAnyPublisher()
155+
}
156+
}

SwapiSwift/Services/MockGraphDataService.swift

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Foundation
1010
import Combine
1111

1212
/// A mock data service confomring to `SwapiService` for use in testing and SwiftUI development.
13+
/// This mock data service is designed for use with `GraphService` helper classes
1314
public struct MockGraphDataService: SwapiService {
1415

1516
/// A key-value store containing arrays of resources conforming to `SwapiResource`.

SwapiSwift/Services/SwapiService.swift

-142
Original file line numberDiff line numberDiff line change
@@ -188,145 +188,3 @@ public struct DataService: SwapiService {
188188
.eraseToAnyPublisher()
189189
}
190190
}
191-
192-
public struct MockDataService<T: SwapiResource>: SwapiService {
193-
194-
let mockData: T
195-
196-
public init(mockData: T) {
197-
self.mockData = mockData
198-
}
199-
200-
public func film(withId resourceId: String) -> AnyPublisher<Film, ServiceError> {
201-
guard let filmData = mockData as? Film else {
202-
fatalError("Expected mock data to be initialized with type Film")
203-
}
204-
return Result.Publisher(filmData).eraseToAnyPublisher()
205-
}
206-
207-
public func person(withId resourceId: String) -> AnyPublisher<Person, ServiceError> {
208-
guard let personData = mockData as? Person else {
209-
fatalError("Expected mock data to be initialized with type Person")
210-
}
211-
return Result.Publisher(personData).eraseToAnyPublisher()
212-
}
213-
214-
public func planet(withId resourceId: String) -> AnyPublisher<Planet, ServiceError> {
215-
guard let planetData = mockData as? Planet else {
216-
fatalError("Expected mock data to be initialized with type Planet")
217-
}
218-
return Result.Publisher(planetData).eraseToAnyPublisher()
219-
}
220-
221-
public func planet(withResourceUrl url: String?) -> AnyPublisher<Planet, ServiceError> {
222-
guard let planetData = mockData as? Planet else {
223-
fatalError("Expected mock data to be initialized with type Planet")
224-
}
225-
return Result.Publisher(planetData).eraseToAnyPublisher()
226-
}
227-
228-
public func species(withId resourceId: String) -> AnyPublisher<Species, ServiceError> {
229-
guard let speciesData = mockData as? Species else {
230-
fatalError("Expected mock data to be initialized with type Species")
231-
}
232-
return Result.Publisher(speciesData).eraseToAnyPublisher()
233-
}
234-
235-
public func starship(withId resourceId: String) -> AnyPublisher<Starship, ServiceError> {
236-
guard let starshipData = mockData as? Starship else {
237-
fatalError("Expected mock data to be initialized with type Starship")
238-
}
239-
return Result.Publisher(starshipData).eraseToAnyPublisher()
240-
}
241-
242-
public func vehicle(withId resourceId: String) -> AnyPublisher<Vehicle, ServiceError> {
243-
guard let vehicleData = mockData as? Vehicle else {
244-
fatalError("Expected mock data to be initialized with type Vehicle")
245-
}
246-
return Result.Publisher(vehicleData).eraseToAnyPublisher()
247-
}
248-
249-
public func allFilms(page: String?) -> AnyPublisher<ResourceRoot<Film>, ServiceError> {
250-
guard let filmsData = mockData as? ResourceRoot<Film> else {
251-
fatalError("Expected mock data to be initialized with type FilmResourceRoot")
252-
}
253-
return Result.Publisher(filmsData).eraseToAnyPublisher()
254-
}
255-
256-
public func allPeople(page: String?) -> AnyPublisher<ResourceRoot<Person>, ServiceError> {
257-
guard let peopleData = mockData as? ResourceRoot<Person> else {
258-
fatalError("Expected mock data to be initialzed with type PersonResourceRoot")
259-
}
260-
return Result.Publisher(peopleData).eraseToAnyPublisher()
261-
}
262-
263-
public func allPlanets(page: String?) -> AnyPublisher<ResourceRoot<Planet>, ServiceError> {
264-
guard let planetsData = mockData as? ResourceRoot<Planet> else {
265-
fatalError("Expected mock data to be initialzed with type PlanetResourceRoot")
266-
}
267-
return Result.Publisher(planetsData).eraseToAnyPublisher()
268-
}
269-
270-
public func allSpecies(page: String?) -> AnyPublisher<ResourceRoot<Species>, ServiceError> {
271-
guard let speciesData = mockData as? ResourceRoot<Species> else {
272-
fatalError("Expected mock data to be initialzed with type SpeciesResourceRoot")
273-
}
274-
return Result.Publisher(speciesData).eraseToAnyPublisher()
275-
}
276-
277-
public func allStarships(page: String?) -> AnyPublisher<ResourceRoot<Starship>, ServiceError> {
278-
guard let starshipsData = mockData as? ResourceRoot<Starship> else {
279-
fatalError("Expected mock data to be initialzed with type StarshipResourceRoot")
280-
}
281-
return Result.Publisher(starshipsData).eraseToAnyPublisher()
282-
}
283-
284-
public func allVehicles(page: String?) -> AnyPublisher<ResourceRoot<Vehicle>, ServiceError> {
285-
guard let vehiclesData = mockData as? ResourceRoot<Vehicle> else {
286-
fatalError("Expected mock data to be initialzed with type VehicleResourceRoot")
287-
}
288-
return Result.Publisher(vehiclesData).eraseToAnyPublisher()
289-
}
290-
291-
public func people(fromResourceUrls urls: [String]) -> AnyPublisher<[Person], ServiceError> {
292-
guard let people = mockData as? [Person] else {
293-
fatalError("Expected mock data to be initialized with type Person array")
294-
}
295-
return Result.Publisher(people).eraseToAnyPublisher()
296-
}
297-
298-
public func starships(fromResourceUrls urls: [String]) -> AnyPublisher<[Starship], ServiceError> {
299-
guard let starships = mockData as? [Starship] else {
300-
fatalError("Expected mock data to be initialized with type Starship array")
301-
}
302-
return Result.Publisher(starships).eraseToAnyPublisher()
303-
}
304-
305-
public func planets(fromResourceUrls urls: [String]) -> AnyPublisher<[Planet], ServiceError> {
306-
guard let planets = mockData as? [Planet] else {
307-
fatalError("Expected mock data to be initialized with type Planet array")
308-
}
309-
return Result.Publisher(planets).eraseToAnyPublisher()
310-
}
311-
312-
public func species(fromResourceUrls urls: [String]) -> AnyPublisher<[Species], ServiceError> {
313-
guard let species = mockData as? [Species] else {
314-
fatalError("Expected mock data to be initialized with type Species array")
315-
}
316-
return Result.Publisher(species).eraseToAnyPublisher()
317-
}
318-
319-
public func vehicles(fromResourceUrls urls: [String]) -> AnyPublisher<[Vehicle], ServiceError> {
320-
guard let vehicles = mockData as? [Vehicle] else {
321-
fatalError("Expected mock data to be initialized with type Vehicle array")
322-
}
323-
return Result.Publisher(vehicles).eraseToAnyPublisher()
324-
}
325-
326-
public func films(fromResourceUrls urls: [String]) -> AnyPublisher<[Film], ServiceError> {
327-
guard let films = mockData as? [Film] else {
328-
fatalError("Expected mock data to be initialized with type Film array")
329-
}
330-
return Result.Publisher(films).eraseToAnyPublisher()
331-
}
332-
}

0 commit comments

Comments
 (0)