From 8e04944eda3eae66064d9ab1384ff9ae0e2be3d4 Mon Sep 17 00:00:00 2001 From: RockfordWei Date: Wed, 17 Jan 2018 17:08:20 -0500 Subject: [PATCH 1/2] Fixing ISS-543 by appending a new body json interface. `public func bodyJSON(_ type: T.Type) -> T?` --- README.md | 3 + Sources/CURLResponse.swift | 4 ++ Tests/PerfectCURLTests/PerfectCURLTests.swift | 62 ++++++------------- 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index d3f4de1..54203e0 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,9 @@ public extension CURLResponse { /// Get the response body decoded from JSON into a [String:Any] dictionary. /// Invalid/non-JSON body data will result in an empty dictionary being returned. public var bodyJSON: [String:Any] + /// Get the response body decoded from JSON into a decodable structure + /// Invalid/non-JSON body data will result in nil + public func bodyJSON(_ type: T.Type) -> T? } ``` diff --git a/Sources/CURLResponse.swift b/Sources/CURLResponse.swift index 9f53cec..a4cbc26 100644 --- a/Sources/CURLResponse.swift +++ b/Sources/CURLResponse.swift @@ -21,6 +21,7 @@ import cURL import PerfectHTTP import PerfectCrypto import PerfectLib +import Foundation enum ResponseReadState { case status, headers, body @@ -300,6 +301,9 @@ public extension CURLResponse { /// Get the response body decoded from JSON into a [String:Any] dictionary. /// Invalid/non-JSON body data will result in an empty dictionary being returned. public var bodyJSON: [String:Any] { do { return try bodyString.jsonDecode() as? [String:Any] ?? [:] } catch { return [:] } } + /// Get the response body decoded from JSON into a decodable structure + /// Invalid/non-JSON body data will result in nil + public func bodyJSON(_ type: T.Type) -> T? { do { return try JSONDecoder().decode(type, from: Data(bytes: bodyBytes)) } catch { return nil } } } diff --git a/Tests/PerfectCURLTests/PerfectCURLTests.swift b/Tests/PerfectCURLTests/PerfectCURLTests.swift index 2db4941..95f68af 100644 --- a/Tests/PerfectCURLTests/PerfectCURLTests.swift +++ b/Tests/PerfectCURLTests/PerfectCURLTests.swift @@ -121,7 +121,22 @@ class PerfectCURLTests: XCTestCase { .addHeader(custom2, ""), .removeHeader(accept), .replaceHeader(custom, customValue)) - + + struct Headers: Codable { + var connection = "" + var host = "" + var extra = "" + var extra2 = "" + private enum CodingKeys: String, CodingKey { + case connection = "Connection" + case host = "Host" + case extra = "X-Extra" + case extra2 = "X-Extra-2" + } + } + struct HeaderJSON: Codable { + var headers = Headers() + } do { let response = try request.perform() let json = response.bodyJSON @@ -133,6 +148,10 @@ class PerfectCURLTests: XCTestCase { XCTAssertNil(headers[accept.standardName]) XCTAssertEqual(customValue, resCustom) XCTAssertEqual("", resCustom2) + guard let headerJSON = response.bodyJSON(HeaderJSON.self) else { + return XCTAssert(false, "Decodable JSON fault") + } + print(headerJSON) } catch { XCTAssert(false, "\(error)") } @@ -313,47 +332,6 @@ class PerfectCURLTests: XCTestCase { } self.waitForExpectations(timeout: 10000) } - -// func testSMTP () { -// var timestamp = time(nil) -// let now = String(cString: asctime(localtime(×tamp))!) -// let sender = "judysmith1964@gmx.com" -// let recipient = sender -// let u = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) -// uuid_generate_random(u) -// let unu = UnsafeMutablePointer.allocate(capacity: 37) -// uuid_unparse_lower(u, unu) -// let uuid = String(validatingUTF8: unu)! -// u.deallocate(capacity: MemoryLayout.size) -// unu.deallocate(capacity: 37) -// -// let content = "Date: \(now)To: \(recipient)\r\nFrom: \(sender)\r\nCc:\r\nBcc:\r\n" + -// "Message-ID: <\(uuid)@perfect.org>\r\n" + -// "Subject: Hello Perfect-CURL\r\n\r\nSMTP test \(now)\r\n\r\n" -// let curl = CURL(url: "smtp://smtp.gmx.com") -// let _ = curl.setOption(CURLOPT_USERNAME, s: sender) -// let _ = curl.setOption(CURLOPT_PASSWORD, s: "abcd1234") -// let _ = curl.setOption(CURLOPT_MAIL_FROM, s: sender) -// let _ = curl.setOption(CURLOPT_MAIL_RCPT, s: recipient) -// let _ = curl.setOption(CURLOPT_VERBOSE, int: 1) -// let _ = curl.setOption(CURLOPT_UPLOAD, int: 1) -// let _ = curl.setOption(CURLOPT_INFILESIZE, int: content.utf8.count) -// var p:[Int32] = [-1, -1] -// let result = pipe(&p) -// XCTAssertEqual(result, 0) -// let fi = fdopen(p[0], "rb") -// let fo = fdopen(p[1], "wb") -// let w = fwrite(content, 1, content.utf8.count, fo) -// fclose(fo) -// XCTAssertEqual(w, content.utf8.count) -// let _ = curl.setOption(CURLOPT_READDATA, v: fi!) -// let r = curl.performFully() -// print(r.0) -// print(String(cString:r.1)) -// print(String(cString:r.2)) -// fclose(fi) -// XCTAssertEqual(r.0, 0) -// } static var allTests : [(String, (PerfectCURLTests) -> () throws -> Void)] { return [ From 1f3e468b884df1c7c7d103145619e6e8b1fba344 Mon Sep 17 00:00:00 2001 From: RockfordWei Date: Wed, 17 Jan 2018 18:38:49 -0500 Subject: [PATCH 2/2] Modifying bodyJSON from returning nil to throws --- README.md | 4 ++-- Sources/CURLResponse.swift | 4 ++-- Tests/PerfectCURLTests/PerfectCURLTests.swift | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 54203e0..2515203 100644 --- a/README.md +++ b/README.md @@ -220,8 +220,8 @@ public extension CURLResponse { /// Invalid/non-JSON body data will result in an empty dictionary being returned. public var bodyJSON: [String:Any] /// Get the response body decoded from JSON into a decodable structure - /// Invalid/non-JSON body data will result in nil - public func bodyJSON(_ type: T.Type) -> T? + /// Invalid/non-JSON body data will throw errors. + public func bodyJSON(_ type: T.Type) throws -> T } ``` diff --git a/Sources/CURLResponse.swift b/Sources/CURLResponse.swift index a4cbc26..f856e51 100644 --- a/Sources/CURLResponse.swift +++ b/Sources/CURLResponse.swift @@ -302,8 +302,8 @@ public extension CURLResponse { /// Invalid/non-JSON body data will result in an empty dictionary being returned. public var bodyJSON: [String:Any] { do { return try bodyString.jsonDecode() as? [String:Any] ?? [:] } catch { return [:] } } /// Get the response body decoded from JSON into a decodable structure - /// Invalid/non-JSON body data will result in nil - public func bodyJSON(_ type: T.Type) -> T? { do { return try JSONDecoder().decode(type, from: Data(bytes: bodyBytes)) } catch { return nil } } + /// Invalid/non-JSON body data will throw errors. + public func bodyJSON(_ type: T.Type) throws -> T { return try JSONDecoder().decode(type, from: Data(bytes: bodyBytes)) } } diff --git a/Tests/PerfectCURLTests/PerfectCURLTests.swift b/Tests/PerfectCURLTests/PerfectCURLTests.swift index 95f68af..f7399eb 100644 --- a/Tests/PerfectCURLTests/PerfectCURLTests.swift +++ b/Tests/PerfectCURLTests/PerfectCURLTests.swift @@ -148,9 +148,7 @@ class PerfectCURLTests: XCTestCase { XCTAssertNil(headers[accept.standardName]) XCTAssertEqual(customValue, resCustom) XCTAssertEqual("", resCustom2) - guard let headerJSON = response.bodyJSON(HeaderJSON.self) else { - return XCTAssert(false, "Decodable JSON fault") - } + let headerJSON = try response.bodyJSON(HeaderJSON.self) print(headerJSON) } catch { XCTAssert(false, "\(error)")