AlamofireObjectMapperTests.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. //
  2. // AlamofireObjectMapperTests.swift
  3. // AlamofireObjectMapperTests
  4. //
  5. // Created by Tristan Himmelman on 2015-04-30.
  6. //
  7. // The MIT License (MIT)
  8. //
  9. // Copyright (c) 2014-2015 Tristan Himmelman
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining a copy
  12. // of this software and associated documentation files (the "Software"), to deal
  13. // in the Software without restriction, including without limitation the rights
  14. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. // copies of the Software, and to permit persons to whom the Software is
  16. // furnished to do so, subject to the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be included in
  19. // all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. // THE SOFTWARE.
  28. import Foundation
  29. import XCTest
  30. import ObjectMapper
  31. import Alamofire
  32. import AlamofireObjectMapper
  33. class AlamofireObjectMapperTests: XCTestCase {
  34. override func setUp() {
  35. super.setUp()
  36. // Put setup code here. This method is called before the invocation of each test method in the class.
  37. }
  38. override func tearDown() {
  39. // Put teardown code here. This method is called after the invocation of each test method in the class.
  40. super.tearDown()
  41. }
  42. func testResponseObject() {
  43. // This is an example of a functional test case.
  44. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/d8bb95982be8a11a2308e779bb9a9707ebe42ede/sample_json"
  45. let expectation = self.expectation(description: "\(URL)")
  46. _ = AF.request(URL, method: .get).responseObject { (response: AFDataResponse<WeatherResponse>) in
  47. expectation.fulfill()
  48. let mappedObject = response.value
  49. XCTAssertNotNil(mappedObject, "Response should not be nil")
  50. XCTAssertNotNil(mappedObject?.location, "Location should not be nil")
  51. XCTAssertNotNil(mappedObject?.threeDayForecast, "ThreeDayForcast should not be nil")
  52. for forecast in mappedObject!.threeDayForecast! {
  53. XCTAssertNotNil(forecast.day, "day should not be nil")
  54. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  55. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  56. }
  57. }
  58. waitForExpectations(timeout: 10) { error in
  59. XCTAssertNil(error, "\(String(describing: error))")
  60. }
  61. }
  62. func testResponseObjectMapToObject() {
  63. // This is an example of a functional test case.
  64. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/d8bb95982be8a11a2308e779bb9a9707ebe42ede/sample_json"
  65. let expectation = self.expectation(description: "\(URL)")
  66. let weatherResponse = WeatherResponse()
  67. weatherResponse.date = Date()
  68. _ = AF.request(URL, method: .get).responseObject(mapToObject: weatherResponse) { (response: AFDataResponse<WeatherResponse>) in
  69. expectation.fulfill()
  70. let mappedObject = response.value
  71. print(weatherResponse)
  72. XCTAssertNotNil(mappedObject, "Response should not be nil")
  73. XCTAssertNotNil(mappedObject?.date, "Date should not be nil") // Date is not in JSON but should not be nil because we mapped onto an existing object with a date set
  74. XCTAssertNotNil(mappedObject?.location, "Location should not be nil")
  75. XCTAssertNotNil(mappedObject?.threeDayForecast, "ThreeDayForcast should not be nil")
  76. for forecast in mappedObject!.threeDayForecast! {
  77. XCTAssertNotNil(forecast.day, "day should not be nil")
  78. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  79. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  80. }
  81. }
  82. waitForExpectations(timeout: 10) { error in
  83. XCTAssertNil(error, "\(String(describing: error))")
  84. }
  85. }
  86. func testResponseObjectWithKeyPath() {
  87. // This is an example of a functional test case.
  88. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/2ee8f34d21e8febfdefb2b3a403f18a43818d70a/sample_keypath_json"
  89. let expectation = self.expectation(description: "\(URL)")
  90. _ = AF.request(URL, method: .get).responseObject(keyPath: "data") { (response: AFDataResponse<WeatherResponse>) in
  91. expectation.fulfill()
  92. let mappedObject = response.value
  93. XCTAssertNotNil(mappedObject, "Response should not be nil")
  94. XCTAssertNotNil(mappedObject?.location, "Location should not be nil")
  95. XCTAssertNotNil(mappedObject?.threeDayForecast, "ThreeDayForcast should not be nil")
  96. for forecast in mappedObject!.threeDayForecast! {
  97. XCTAssertNotNil(forecast.day, "day should not be nil")
  98. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  99. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  100. }
  101. }
  102. waitForExpectations(timeout: 10) { error in
  103. XCTAssertNil(error, "\(String(describing: error))")
  104. }
  105. }
  106. func testResponseObjectWithNestedKeyPath() {
  107. // This is an example of a functional test case.
  108. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/97231a04e6e4970612efcc0b7e0c125a83e3de6e/sample_keypath_json"
  109. let expectation = self.expectation(description: "\(URL)")
  110. _ = AF.request(URL, method: .get).responseObject(keyPath: "response.data") { (response: AFDataResponse<WeatherResponse>) in
  111. expectation.fulfill()
  112. let mappedObject = response.value
  113. XCTAssertNotNil(mappedObject, "Response should not be nil")
  114. XCTAssertNotNil(mappedObject?.location, "Location should not be nil")
  115. XCTAssertNotNil(mappedObject?.threeDayForecast, "ThreeDayForcast should not be nil")
  116. for forecast in mappedObject!.threeDayForecast! {
  117. XCTAssertNotNil(forecast.day, "day should not be nil")
  118. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  119. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  120. }
  121. }
  122. waitForExpectations(timeout: 10) { error in
  123. XCTAssertNil(error, "\(String(describing: error))")
  124. }
  125. }
  126. func testResponseArray() {
  127. // This is an example of a functional test case.
  128. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/f583be1121dbc5e9b0381b3017718a70c31054f7/sample_array_json"
  129. let expectation = self.expectation(description: "\(URL)")
  130. _ = AF.request(URL, method: .get).responseArray { (response: AFDataResponse<[Forecast]>) in
  131. expectation.fulfill()
  132. let mappedArray = response.value
  133. XCTAssertNotNil(mappedArray, "Response should not be nil")
  134. XCTAssertTrue(mappedArray?.count == 3, "Didn't parse correct amount of objects")
  135. for forecast in mappedArray! {
  136. XCTAssertNotNil(forecast.day, "day should not be nil")
  137. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  138. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  139. }
  140. }
  141. waitForExpectations(timeout: 10) { error in
  142. XCTAssertNil(error, "\(String(describing: error))")
  143. }
  144. }
  145. func testArrayResponseArrayWithKeyPath() {
  146. // This is an example of a functional test case.
  147. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/d8bb95982be8a11a2308e779bb9a9707ebe42ede/sample_json"
  148. let expectation = self.expectation(description: "\(URL)")
  149. _ = AF.request(URL, method: .get).responseArray(keyPath: "three_day_forecast") { (response: AFDataResponse<[Forecast]>) in
  150. expectation.fulfill()
  151. let mappedArray = response.value
  152. XCTAssertNotNil(mappedArray, "Response should not be nil")
  153. for forecast in mappedArray! {
  154. XCTAssertNotNil(forecast.day, "day should not be nil")
  155. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  156. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  157. }
  158. }
  159. waitForExpectations(timeout: 10) { error in
  160. XCTAssertNil(error, "\(String(describing: error))")
  161. }
  162. }
  163. func testArrayResponseArrayWithNestedKeyPath() {
  164. // This is an example of a functional test case.
  165. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/97231a04e6e4970612efcc0b7e0c125a83e3de6e/sample_keypath_json"
  166. let expectation = self.expectation(description: "\(URL)")
  167. _ = AF.request(URL, method: .get).responseArray(keyPath: "response.data.three_day_forecast") { (response: AFDataResponse<[Forecast]>) in
  168. expectation.fulfill()
  169. let mappedArray = response.value
  170. XCTAssertNotNil(mappedArray, "Response should not be nil")
  171. for forecast in mappedArray! {
  172. XCTAssertNotNil(forecast.day, "day should not be nil")
  173. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  174. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  175. }
  176. }
  177. waitForExpectations(timeout: 10) { error in
  178. XCTAssertNil(error, "\(String(describing: error))")
  179. }
  180. }
  181. // MARK: - Immutable Tests
  182. func testResponseImmutableObject() {
  183. // This is an example of a functional test case.
  184. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/d8bb95982be8a11a2308e779bb9a9707ebe42ede/sample_json"
  185. let expectation = self.expectation(description: "\(URL)")
  186. _ = AF.request(URL, method: .get).responseObject { (response: AFDataResponse<WeatherResponseImmutable>) in
  187. expectation.fulfill()
  188. let mappedObject = response.value
  189. XCTAssertNotNil(mappedObject, "Response should not be nil")
  190. XCTAssertNotNil(mappedObject?.location, "Location should not be nil")
  191. XCTAssertNotNil(mappedObject?.threeDayForecast, "ThreeDayForcast should not be nil")
  192. for forecast in mappedObject!.threeDayForecast {
  193. XCTAssertNotNil(forecast.day, "day should not be nil")
  194. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  195. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  196. }
  197. }
  198. waitForExpectations(timeout: 10) { error in
  199. XCTAssertNil(error, "\(String(describing: error))")
  200. }
  201. }
  202. func testResponseImmutableArray() {
  203. // This is an example of a functional test case.
  204. let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/f583be1121dbc5e9b0381b3017718a70c31054f7/sample_array_json"
  205. let expectation = self.expectation(description: "\(URL)")
  206. _ = AF.request(URL, method: .get).responseArray { (response: AFDataResponse<[ImmutableForecast]>) in
  207. expectation.fulfill()
  208. let mappedArray = response.value
  209. XCTAssertNotNil(mappedArray, "Response should not be nil")
  210. XCTAssertTrue(mappedArray?.count == 3, "Didn't parse correct amount of objects")
  211. for forecast in mappedArray! {
  212. XCTAssertNotNil(forecast.day, "day should not be nil")
  213. XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
  214. XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
  215. }
  216. }
  217. waitForExpectations(timeout: 10) { error in
  218. XCTAssertNil(error, "\(String(describing: error))")
  219. }
  220. }
  221. }
  222. // MARK: - Response classes
  223. // MARK: - ImmutableMappable
  224. class ImmutableWeatherResponse: ImmutableMappable {
  225. let location: String
  226. let threeDayForecast: [ImmutableForecast]
  227. required init(map: Map) throws {
  228. location = try map.value("location")
  229. threeDayForecast = try map.value("three_day_forecast")
  230. }
  231. func mapping(map: Map) {
  232. location >>> map["location"]
  233. threeDayForecast >>> map["three_day_forecast"]
  234. }
  235. }
  236. class ImmutableForecast: ImmutableMappable {
  237. let day: String
  238. let temperature: Int
  239. let conditions: String
  240. required init(map: Map) throws {
  241. day = try map.value("day")
  242. temperature = try map.value("temperature")
  243. conditions = try map.value("conditions")
  244. }
  245. func mapping(map: Map) {
  246. day >>> map["day"]
  247. temperature >>> map["temperature"]
  248. conditions >>> map["conditions"]
  249. }
  250. }
  251. // MARK: - Mappable
  252. class WeatherResponse: Mappable {
  253. var location: String?
  254. var threeDayForecast: [Forecast]?
  255. var date: Date?
  256. init(){}
  257. required init?(map: Map){
  258. }
  259. func mapping(map: Map) {
  260. location <- map["location"]
  261. threeDayForecast <- map["three_day_forecast"]
  262. }
  263. }
  264. class Forecast: Mappable {
  265. var day: String?
  266. var temperature: Int?
  267. var conditions: String?
  268. required init?(map: Map){
  269. }
  270. func mapping(map: Map) {
  271. day <- map["day"]
  272. temperature <- map["temperature"]
  273. conditions <- map["conditions"]
  274. }
  275. }
  276. struct WeatherResponseImmutable: ImmutableMappable {
  277. let location: String
  278. var threeDayForecast: [Forecast]
  279. var date: Date?
  280. init(map: Map) throws {
  281. location = try map.value("location")
  282. threeDayForecast = try map.value("three_day_forecast")
  283. }
  284. func mapping(map: Map) {
  285. location >>> map["location"]
  286. threeDayForecast >>> map["three_day_forecast"]
  287. }
  288. }
  289. struct ForecastImmutable: ImmutableMappable {
  290. let day: String
  291. var temperature: Int
  292. var conditions: String?
  293. init(map: Map) throws {
  294. day = try map.value("day")
  295. temperature = try map.value("temperature")
  296. conditions = try? map.value("conditions")
  297. }
  298. func mapping(map: Map) {
  299. day >>> map["day"]
  300. temperature >>> map["temperature"]
  301. conditions >>> map["conditions"]
  302. }
  303. }