Browse Source

Refactored all response serialization to leverage the new Response struct.

Christian Noon 10 years ago
parent
commit
8a6ee8427d
5 changed files with 199 additions and 247 deletions
  1. 38 38
      Source/ResponseSerialization.swift
  2. 10 19
      Tests/DownloadTests.swift
  3. 10 18
      Tests/ManagerTests.swift
  4. 41 48
      Tests/RequestTests.swift
  5. 100 124
      Tests/ResponseTests.swift

+ 38 - 38
Source/ResponseSerialization.swift

@@ -27,42 +27,44 @@ import Foundation
 /**
     The type in which all response serializers must conform to in order to serialize a response.
 */
-public protocol ResponseSerializer {
-    /// The type of serialized object to be created by this `ResponseSerializer`.
+public protocol ResponseSerializerType {
+    /// The type of serialized object to be created by this `ResponseSerializerType`.
     typealias SerializedObject
-    typealias Error: ErrorType
+
+    /// The type of error to be created by this `ResponseSerializer` if serialization fails.
+    typealias ErrorObject: ErrorType
 
     /**
         A closure used by response handlers that takes a request, response, and data and returns a result.
     */
-    var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<SerializedObject, Error> { get }
+    var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<SerializedObject, ErrorObject> { get }
 }
 
 // MARK: -
 
 /**
-    A generic `ResponseSerializer` used to serialize a request, response, and data into a serialized object.
+    A generic `ResponseSerializerType` used to serialize a request, response, and data into a serialized object.
 */
-public struct GenericResponseSerializer<T, E: ErrorType>: ResponseSerializer {
+public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
     /// The type of serialized object to be created by this `ResponseSerializer`.
-    public typealias SerializedObject = T
+    public typealias SerializedObject = Value
 
     /// The type of error to be created by this `ResponseSerializer` if serialization fails.
-    public typealias Error = E
+    public typealias ErrorObject = Error
 
     /**
         A closure used by response handlers that takes a request, response, and data and returns a result.
     */
-    public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<T, E>
+    public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<Value, Error>
 
     /**
-        Initializes the `GenericResponseSerializer` instance with the given serialize response closure.
+        Initializes the `ResponseSerializer` instance with the given serialize response closure.
 
         - parameter serializeResponse: The closure used to serialize the response.
 
         - returns: The new generic response serializer instance.
     */
-    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<T, E>) {
+    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<Value, Error>) {
         self.serializeResponse = serializeResponse
     }
 }
@@ -103,17 +105,24 @@ extension Request {
 
         - returns: The request.
     */
-    public func response<T: ResponseSerializer, V where T.SerializedObject == V>(
+    public func response<T: ResponseSerializerType>(
         queue queue: dispatch_queue_t? = nil,
         responseSerializer: T,
-        completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, Result<V, T.Error>) -> Void)
+        completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void)
         -> Self
     {
         delegate.queue.addOperationWithBlock {
             let result = responseSerializer.serializeResponse(self.request, self.response, self.delegate.data)
 
             dispatch_async(queue ?? dispatch_get_main_queue()) {
-                completionHandler(self.request, self.response, self.delegate.data, result)
+                let response = Response<T.SerializedObject, T.ErrorObject>(
+                    request: self.request,
+                    response: self.response,
+                    data: self.delegate.data,
+                    result: result
+                )
+
+                completionHandler(response)
             }
         }
 
@@ -130,8 +139,8 @@ extension Request {
 
         - returns: A data response serializer.
     */
-    public static func dataResponseSerializer() -> GenericResponseSerializer<NSData, NSError> {
-        return GenericResponseSerializer { _, _, data in
+    public static func dataResponseSerializer() -> ResponseSerializer<NSData, NSError> {
+        return ResponseSerializer { _, _, data in
             guard let validData = data where validData.length > 0 else {
                 let failureReason = "Data could not be serialized. Input data was nil or zero length."
                 let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
@@ -145,16 +154,11 @@ extension Request {
     /**
         Adds a handler to be called once the request has finished.
 
-        - parameter completionHandler: The code to be executed once the request has finished. The closure takes 4
-                                       arguments: the URL request, the URL response, the server data and the result
-                                       produced while extracting the data.
+        - parameter completionHandler: The code to be executed once the request has finished.
 
         - returns: The request.
     */
-    public func responseData(
-        completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, Result<NSData, NSError>) -> Void)
-        -> Self
-    {
+    public func responseData(completionHandler: Response<NSData, NSError> -> Void) -> Self {
         return response(responseSerializer: Request.dataResponseSerializer(), completionHandler: completionHandler)
     }
 }
@@ -174,9 +178,9 @@ extension Request {
     */
     public static func stringResponseSerializer(
         var encoding encoding: NSStringEncoding? = nil)
-        -> GenericResponseSerializer<String, NSError>
+        -> ResponseSerializer<String, NSError>
     {
-        return GenericResponseSerializer { _, response, data in
+        return ResponseSerializer { _, response, data in
             guard let validData = data where validData.length > 0 else {
                 let failureReason = "String could not be serialized. Input data was nil or zero length."
                 let error = Error.errorWithCode(.StringSerializationFailed, failureReason: failureReason)
@@ -207,15 +211,13 @@ extension Request {
         - parameter encoding:          The string encoding. If `nil`, the string encoding will be determined from the 
                                        server response, falling back to the default HTTP default character set, 
                                        ISO-8859-1.
-        - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3
-                                       arguments: the URL request, the URL response, the server data and the result 
-                                       produced while creating the string.
+        - parameter completionHandler: A closure to be executed once the request has finished.
 
         - returns: The request.
     */
     public func responseString(
         encoding encoding: NSStringEncoding? = nil,
-        completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, Result<String, NSError>) -> Void)
+        completionHandler: Response<String, NSError> -> Void)
         -> Self
     {
         return response(
@@ -239,9 +241,9 @@ extension Request {
     */
     public static func JSONResponseSerializer(
         options options: NSJSONReadingOptions = .AllowFragments)
-        -> GenericResponseSerializer<AnyObject, NSError>
+        -> ResponseSerializer<AnyObject, NSError>
     {
-        return GenericResponseSerializer { _, _, data in
+        return ResponseSerializer { _, _, data in
             guard let validData = data where validData.length > 0 else {
                 let failureReason = "JSON could not be serialized. Input data was nil or zero length."
                 let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
@@ -261,15 +263,13 @@ extension Request {
         Adds a handler to be called once the request has finished.
 
         - parameter options:           The JSON serialization reading options. `.AllowFragments` by default.
-        - parameter completionHandler: A closure to be executed once the request has finished. The closure takes 3
-                                       arguments: the URL request, the URL response, the server data and the result 
-                                       produced while creating the JSON object.
+        - parameter completionHandler: A closure to be executed once the request has finished.
 
         - returns: The request.
     */
     public func responseJSON(
         options options: NSJSONReadingOptions = .AllowFragments,
-        completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, Result<AnyObject, NSError>) -> Void)
+        completionHandler: Response<AnyObject, NSError> -> Void)
         -> Self
     {
         return response(
@@ -293,9 +293,9 @@ extension Request {
     */
     public static func propertyListResponseSerializer(
         options options: NSPropertyListReadOptions = NSPropertyListReadOptions())
-        -> GenericResponseSerializer<AnyObject, NSError>
+        -> ResponseSerializer<AnyObject, NSError>
     {
-        return GenericResponseSerializer { _, _, data in
+        return ResponseSerializer { _, _, data in
             guard let validData = data where validData.length > 0 else {
                 let failureReason = "Property list could not be serialized. Input data was nil or zero length."
                 let error = Error.errorWithCode(.PropertyListSerializationFailed, failureReason: failureReason)
@@ -323,7 +323,7 @@ extension Request {
     */
     public func responsePropertyList(
         options options: NSPropertyListReadOptions = NSPropertyListReadOptions(),
-        completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, Result<AnyObject, NSError>) -> Void)
+        completionHandler: Response<AnyObject, NSError> -> Void)
         -> Self
     {
         return response(

+ 10 - 19
Tests/DownloadTests.swift

@@ -429,38 +429,29 @@ class DownloadResumeDataTestCase: BaseTestCase {
     func testThatCancelledDownloadResumeDataIsAvailableWithJSONResponseSerializer() {
         // Given
         let expectation = expectationWithDescription("Download should be cancelled")
-
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         let download = Alamofire.download(.GET, URLString, destination: destination)
         download.progress { _, _, _ in
             download.cancel()
         }
-        download.responseJSON { responseRequest, responseResponse, responseData, responseResult in
-            request = responseRequest
-            response = responseResponse
-            data = responseData
-            result = responseResult
-
+        download.responseJSON { closureResponse in
+            response = closureResponse
             expectation.fulfill()
         }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-
-        if let result = result {
-            XCTAssertTrue(result.isFailure, "result should be a failure")
-            XCTAssertTrue(result.error != nil, "error should not be nil")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isFailure, "result should be failure")
+            XCTAssertNotNil(response.result.error, "result error should not be nil")
         } else {
-            XCTFail("result should not be nil")
+            XCTFail("response should not be nil")
         }
 
         XCTAssertNotNil(download.resumeData, "resume data should not be nil")

+ 10 - 18
Tests/ManagerTests.swift

@@ -139,34 +139,26 @@ class ManagerConfigurationHeadersTestCase: BaseTestCase {
 
         let expectation = expectationWithDescription("request should complete successfully")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         manager.request(.GET, "https://httpbin.org/headers")
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-
-        if let result = result {
-            XCTAssertTrue(result.isSuccess, "result should be a success")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be a success")
 
             if let
-                headers = result.value?["headers" as NSString] as? [String: String],
+                headers = response.result.value?["headers" as NSString] as? [String: String],
                 authorization = headers["Authorization"]
             {
                 XCTAssertEqual(authorization, "Bearer 123456", "authorization header value does not match")
@@ -174,7 +166,7 @@ class ManagerConfigurationHeadersTestCase: BaseTestCase {
                 XCTFail("failed to extract authorization header value")
             }
         } else {
-            XCTFail("result should not be nil")
+            XCTFail("response should not be nil")
         }
     }
 }

+ 41 - 48
Tests/RequestTests.swift

@@ -290,40 +290,36 @@ class RequestResponseTestCase: BaseTestCase {
 
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.POST, URLString, parameters: parameters)
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertNotNil(result, "result should be nil")
-
-        if let
-            JSON = result?.value as? [String: AnyObject],
-            form = JSON["form"] as? [String: String]
-        {
-            XCTAssertEqual(form["french"], parameters["french"], "french parameter value should match form value")
-            XCTAssertEqual(form["japanese"], parameters["japanese"], "japanese parameter value should match form value")
-            XCTAssertEqual(form["arabic"], parameters["arabic"], "arabic parameter value should match form value")
-            XCTAssertEqual(form["emoji"], parameters["emoji"], "emoji parameter value should match form value")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+
+            if let
+                JSON = response.result.value as? [String: AnyObject],
+                form = JSON["form"] as? [String: String]
+            {
+                XCTAssertEqual(form["french"], parameters["french"], "french parameter value should match form value")
+                XCTAssertEqual(form["japanese"], parameters["japanese"], "japanese parameter value should match form value")
+                XCTAssertEqual(form["arabic"], parameters["arabic"], "arabic parameter value should match form value")
+                XCTAssertEqual(form["emoji"], parameters["emoji"], "emoji parameter value should match form value")
+            } else {
+                XCTFail("form parameter in JSON should not be nil")
+            }
         } else {
-            XCTFail("form parameter in JSON should not be nil")
+            XCTFail("response should not be nil")
         }
     }
 
@@ -353,39 +349,36 @@ class RequestResponseTestCase: BaseTestCase {
 
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.POST, URLString, parameters: parameters)
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
-        }
+            }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertNotNil(result, "result should be nil")
-
-        if let
-            JSON = result?.value as? [String: AnyObject],
-            form = JSON["form"] as? [String: String]
-        {
-            XCTAssertEqual(form["email"], parameters["email"], "email parameter value should match form value")
-            XCTAssertEqual(form["png_image"], parameters["png_image"], "png_image parameter value should match form value")
-            XCTAssertEqual(form["jpeg_image"], parameters["jpeg_image"], "jpeg_image parameter value should match form value")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+
+            if let
+                JSON = response.result.value as? [String: AnyObject],
+                form = JSON["form"] as? [String: String]
+            {
+                XCTAssertEqual(form["email"], parameters["email"], "email parameter value should match form value")
+                XCTAssertEqual(form["png_image"], parameters["png_image"], "png_image parameter value should match form value")
+                XCTAssertEqual(form["jpeg_image"], parameters["jpeg_image"], "jpeg_image parameter value should match form value")
+            } else {
+                XCTFail("form parameter in JSON should not be nil")
+            }
         } else {
-            XCTFail("form parameter in JSON should not be nil")
+            XCTFail("response should not be nil")
         }
     }
 }

+ 100 - 124
Tests/ResponseTests.swift

@@ -30,29 +30,26 @@ class ResponseDataTestCase: BaseTestCase {
         let URLString = "https://httpbin.org/get"
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<NSData, NSError>?
+        var response: Response<NSData, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseData { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseData { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isSuccess ?? false, "result should be success")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 
     func testThatResponseDataReturnsFailureResultWithOptionalDataAndError() {
@@ -60,29 +57,26 @@ class ResponseDataTestCase: BaseTestCase {
         let URLString = "https://invalid-url-here.org/this/does/not/exist"
         let expectation = expectationWithDescription("request should fail with 404")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<NSData, NSError>?
+        var response: Response<NSData, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseData { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseData { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNil(response, "response should be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isFailure ?? false, "result should be failure")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNil(response.response, "response should be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isFailure, "result should be failure")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 }
 
@@ -94,29 +88,26 @@ class ResponseStringTestCase: BaseTestCase {
         let URLString = "https://httpbin.org/get"
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<String, NSError>?
+        var response: Response<String, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseString { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseString { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isSuccess ?? false, "result should be success")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 
     func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
@@ -124,29 +115,26 @@ class ResponseStringTestCase: BaseTestCase {
         let URLString = "https://invalid-url-here.org/this/does/not/exist"
         let expectation = expectationWithDescription("request should fail with 404")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<String, NSError>?
+        var response: Response<String, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseString { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseString { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNil(response, "response should be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isFailure ?? false, "result should be failure")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNil(response.response, "response should be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isFailure, "result should be failure")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 }
 
@@ -158,29 +146,26 @@ class ResponseJSONTestCase: BaseTestCase {
         let URLString = "https://httpbin.org/get"
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isSuccess ?? false, "result should be success")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 
     func testThatResponseStringReturnsFailureResultWithOptionalDataAndError() {
@@ -188,29 +173,26 @@ class ResponseJSONTestCase: BaseTestCase {
         let URLString = "https://invalid-url-here.org/this/does/not/exist"
         let expectation = expectationWithDescription("request should fail with 404")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNil(response, "response should be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isFailure ?? false, "result should be failure")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNil(response.response, "response should be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isFailure, "result should be failure")
+        } else {
+            XCTFail("response should not be nil")
+        }
     }
 
     func testThatResponseJSONReturnsSuccessResultForGETRequest() {
@@ -218,36 +200,33 @@ class ResponseJSONTestCase: BaseTestCase {
         let URLString = "https://httpbin.org/get"
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isSuccess ?? false, "result should be success")
-
-        // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
-        // - https://openradar.appspot.com/radar?id=5517037090635776
-        if let args = result?.value?["args" as NSString] as? [String: String] {
-            XCTAssertEqual(args, ["foo": "bar"], "args should match parameters")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+
+            // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
+            // - https://openradar.appspot.com/radar?id=5517037090635776
+            if let args = response.result.value?["args" as NSString] as? [String: String] {
+                XCTAssertEqual(args, ["foo": "bar"], "args should match parameters")
+            } else {
+                XCTFail("args should not be nil")
+            }
         } else {
-            XCTFail("args should not be nil")
+            XCTFail("response should not be nil")
         }
     }
 
@@ -256,36 +235,33 @@ class ResponseJSONTestCase: BaseTestCase {
         let URLString = "https://httpbin.org/post"
         let expectation = expectationWithDescription("request should succeed")
 
-        var request: NSURLRequest?
-        var response: NSHTTPURLResponse?
-        var data: NSData?
-        var result: Result<AnyObject, NSError>?
+        var response: Response<AnyObject, NSError>?
 
         // When
         Alamofire.request(.POST, URLString, parameters: ["foo": "bar"])
-            .responseJSON { responseRequest, responseResponse, responseData, responseResult in
-                request = responseRequest
-                response = responseResponse
-                data = responseData
-                result = responseResult
-
+            .responseJSON { closureResponse in
+                response = closureResponse
                 expectation.fulfill()
             }
 
         waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
 
         // Then
-        XCTAssertNotNil(request, "request should not be nil")
-        XCTAssertNotNil(response, "response should not be nil")
-        XCTAssertNotNil(data, "data should not be nil")
-        XCTAssertTrue(result?.isSuccess ?? false, "result should be success")
-
-        // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
-        // - https://openradar.appspot.com/radar?id=5517037090635776
-        if let form = result?.value?["form" as NSString] as? [String: String] {
-            XCTAssertEqual(form, ["foo": "bar"], "form should match parameters")
+        if let response = response {
+            XCTAssertNotNil(response.request, "request should not be nil")
+            XCTAssertNotNil(response.response, "response should not be nil")
+            XCTAssertNotNil(response.data, "data should not be nil")
+            XCTAssertTrue(response.result.isSuccess, "result should be success")
+
+            // The `as NSString` cast is necessary due to a compiler bug. See the following rdar for more info.
+            // - https://openradar.appspot.com/radar?id=5517037090635776
+            if let form = response.result.value?["form" as NSString] as? [String: String] {
+                XCTAssertEqual(form, ["foo": "bar"], "form should match parameters")
+            } else {
+                XCTFail("form should not be nil")
+            }
         } else {
-            XCTFail("form should not be nil")
+            XCTFail("response should not be nil")
         }
     }
 }