[api-upload-refactor] Add test target, relax decode constraints, add HTTPBody + MultipartForm
- Package: new LCEssentialsTests target (runs on iOS simulator) - JSONDecoder.decode: T: Codable -> T: Decodable & Sendable (4 overloads); remove try! in decode(fromURL:); honour encoding param in decode(_:using:) - Propagate & Sendable to Data.object, Dictionary.toObjetct, API.request return - LCEHTTPBody: HTTPBody protocol, JSONBody, FormURLEncodedBody, RawBody, factories - LCEMultipartForm: multipart builder, OutputStream-streamed serialize(), in-memory + on-disk file parts, ported mimeType(for:) - Tests: StubURLProtocol harness + 15 tests
This commit is contained in:
58
Tests/LCEssentialsTests/HTTPBodyTests.swift
Normal file
58
Tests/LCEssentialsTests/HTTPBodyTests.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
import XCTest
|
||||
@testable import LCEssentials
|
||||
|
||||
private struct SamplePayload: Encodable, Sendable {
|
||||
let name: String
|
||||
let age: Int
|
||||
}
|
||||
|
||||
final class HTTPBodyTests: XCTestCase {
|
||||
|
||||
// MARK: - JSONBody
|
||||
|
||||
func testJSONBodyEncodesPayloadAndContentType() throws {
|
||||
let payload = SamplePayload(name: "loverde", age: 3)
|
||||
let (data, contentType) = try JSONBody(payload).encoded()
|
||||
|
||||
XCTAssertEqual(contentType, "application/json; charset=UTF-8")
|
||||
|
||||
let decoded = try JSONDecoder().decode([String: AnyDecodable].self, from: data)
|
||||
XCTAssertEqual(decoded["name"]?.value as? String, "loverde")
|
||||
XCTAssertEqual(decoded["age"]?.value as? Int, 3)
|
||||
}
|
||||
|
||||
func testJSONBodyFactory() throws {
|
||||
let (data, _) = try jsonBody(SamplePayload(name: "x", age: 1)).encoded()
|
||||
XCTAssertFalse(data.isEmpty)
|
||||
}
|
||||
|
||||
// MARK: - FormURLEncodedBody
|
||||
|
||||
func testFormURLEncodedEncodesPairsAndPercentEscapes() throws {
|
||||
let (data, contentType) = try FormURLEncodedBody(["a": "1", "b": "two words"]).encoded()
|
||||
|
||||
XCTAssertEqual(contentType, "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
|
||||
let pairs = Set(String(data: data, encoding: .utf8)!.split(separator: "&").map(String.init))
|
||||
XCTAssertEqual(pairs, ["a=1", "b=two%20words"])
|
||||
}
|
||||
|
||||
func testFormURLEncodedEscapesReservedCharactersInsteadOfDropping() throws {
|
||||
let (data, _) = try FormURLEncodedBody(["q": "a&b=c"]).encoded()
|
||||
let body = String(data: data, encoding: .utf8)!
|
||||
XCTAssertEqual(body, "q=a%26b%3Dc")
|
||||
}
|
||||
}
|
||||
|
||||
/// Minimal type-erased decoder for asserting JSON shape in tests.
|
||||
struct AnyDecodable: Decodable {
|
||||
let value: Any
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.singleValueContainer()
|
||||
if let i = try? c.decode(Int.self) { value = i }
|
||||
else if let s = try? c.decode(String.self) { value = s }
|
||||
else if let b = try? c.decode(Bool.self) { value = b }
|
||||
else if let d = try? c.decode(Double.self) { value = d }
|
||||
else { value = "" }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user