diff --git a/Sources/MultipartFormData/Boundary.swift b/Sources/MultipartFormData/Boundary.swift index 8e9d4da..8e24c5f 100644 --- a/Sources/MultipartFormData/Boundary.swift +++ b/Sources/MultipartFormData/Boundary.swift @@ -38,9 +38,12 @@ extension Boundary { public var debugDescription: String { switch self { - case .empty: return "Boundary must not be empty." - case .tooLong: return "Boundary is too long. Max size is 70 characters." - case .noASCII: return "Boundary contains at least one character that is not ASCII compatible." + case .empty: + return "Boundary must not be empty." + case .tooLong: + return "Boundary is too long. Max size is 70 characters." + case .noASCII: + return "Boundary contains at least one character that is not ASCII compatible." } } } diff --git a/Sources/MultipartFormData/MediaType.swift b/Sources/MultipartFormData/MediaType.swift index dd72fa0..0ad9d2e 100644 --- a/Sources/MultipartFormData/MediaType.swift +++ b/Sources/MultipartFormData/MediaType.swift @@ -37,6 +37,7 @@ extension MediaType { public static let multipartFormData = MediaType(type: "multipart", subtype: "form-data") public static let textPlain = MediaType(type: "text", subtype: "plain") + public static let textCsv = MediaType(type: "text", subtype: "csv") public static let textHtml = MediaType(type: "text", subtype: "html") public static let textCss = MediaType(type: "text", subtype: "css") @@ -63,6 +64,34 @@ extension MediaType { } // swiftlint:enable missing_docs +// MARK: - UniformTypeIdentifiers + +#if canImport(UniformTypeIdentifiers) +import UniformTypeIdentifiers + +extension MediaType { + /// Create a media type from a uniform type. + /// - Parameter uniformType: The uniform type (UTType). + @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) + public init?(uniformType: UTType) { + guard let mimeTypeSplit = uniformType.preferredMIMEType?.split(separator: "/") else { return nil } + guard mimeTypeSplit.count == 2 else { return nil } + self.type = String(mimeTypeSplit[0]) + self.subtype = String(mimeTypeSplit[1]) + } +} + +@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) +extension UTType { + /// Create a uniform type from a media type. + /// - Parameter mediaType: The media type. + /// - Parameter supertype: Another UTType instance that the resulting type must conform to; for example, UTTypeData. + public init?(mediaType: MediaType, conformingTo supertype: UTType = .data) { + self.init(mimeType: mediaType._text, conformingTo: supertype) + } +} +#endif + // MARK: - Debug extension MediaType: CustomDebugStringConvertible { diff --git a/Tests/MultipartFormDataTests/BoundaryTests.swift b/Tests/MultipartFormDataTests/BoundaryTests.swift index 1ee0f05..dd2c11e 100644 --- a/Tests/MultipartFormDataTests/BoundaryTests.swift +++ b/Tests/MultipartFormDataTests/BoundaryTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class BoundaryTests: XCTestCase { - func testEmpty() { XCTAssertThrowsError(try Boundary(uncheckedBoundary: "")) { error in XCTAssertEqual(error as? Boundary.InvalidBoundaryError, .empty) diff --git a/Tests/MultipartFormDataTests/Builder/BodyDataBuilderTests.swift b/Tests/MultipartFormDataTests/Builder/BodyDataBuilderTests.swift index e3c71a3..bb92f5c 100644 --- a/Tests/MultipartFormDataTests/Builder/BodyDataBuilderTests.swift +++ b/Tests/MultipartFormDataTests/Builder/BodyDataBuilderTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class BodyDataBuilderTests: XCTestCase { - func testSingleData() { let data = _buildData { Data("a".utf8) diff --git a/Tests/MultipartFormDataTests/Builder/HTTPHeaderBuilderTests.swift b/Tests/MultipartFormDataTests/Builder/HTTPHeaderBuilderTests.swift index 7b229db..19b82b5 100644 --- a/Tests/MultipartFormDataTests/Builder/HTTPHeaderBuilderTests.swift +++ b/Tests/MultipartFormDataTests/Builder/HTTPHeaderBuilderTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class HTTPHeaderBuilderTests: XCTestCase { - func testAvailableHeaderCombinations() { let dispositionResult = _buildHeader { ContentDisposition(name: "a") diff --git a/Tests/MultipartFormDataTests/Builder/MultipartFormDataBuilderTests.swift b/Tests/MultipartFormDataTests/Builder/MultipartFormDataBuilderTests.swift index 66efb8e..c64d9ca 100644 --- a/Tests/MultipartFormDataTests/Builder/MultipartFormDataBuilderTests.swift +++ b/Tests/MultipartFormDataTests/Builder/MultipartFormDataBuilderTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class MultipartFormDataBuilderTests: XCTestCase { - func testSingleSubpart() throws { let subparts = _buildSubparts { Subpart { diff --git a/Tests/MultipartFormDataTests/ContentDispositionTests.swift b/Tests/MultipartFormDataTests/ContentDispositionTests.swift index a10e182..71ce853 100644 --- a/Tests/MultipartFormDataTests/ContentDispositionTests.swift +++ b/Tests/MultipartFormDataTests/ContentDispositionTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class ContentDispositionTests: XCTestCase { - func testPercentEncodingError() throws { XCTAssertNoThrow(try ContentDisposition(uncheckedName: "a", uncheckedFilename: "a")) diff --git a/Tests/MultipartFormDataTests/ContentTypeTests.swift b/Tests/MultipartFormDataTests/ContentTypeTests.swift index 9f387a6..00afb3c 100644 --- a/Tests/MultipartFormDataTests/ContentTypeTests.swift +++ b/Tests/MultipartFormDataTests/ContentTypeTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class ContentTypeTests: XCTestCase { - func testBoundaryParameters() throws { let contentType = ContentType(boundary: try Boundary(uncheckedBoundary: "test")) diff --git a/Tests/MultipartFormDataTests/HTTPHeaderFieldTests.swift b/Tests/MultipartFormDataTests/HTTPHeaderFieldTests.swift index b67d6cf..99b51d9 100644 --- a/Tests/MultipartFormDataTests/HTTPHeaderFieldTests.swift +++ b/Tests/MultipartFormDataTests/HTTPHeaderFieldTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class HTTPHeaderFieldTests: XCTestCase { - func testDebugDescription() { let parameter = HTTPHeaderParameter("name", value: "value") let testHeaderField = TestHeaderField(value: "value", parameters: [parameter]) diff --git a/Tests/MultipartFormDataTests/HTTPHeaderParameterTests.swift b/Tests/MultipartFormDataTests/HTTPHeaderParameterTests.swift index b1b9420..be76ad0 100644 --- a/Tests/MultipartFormDataTests/HTTPHeaderParameterTests.swift +++ b/Tests/MultipartFormDataTests/HTTPHeaderParameterTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class HTTPHeaderParameterTests: XCTestCase { - func testArrayText() { let singleParameter = [ HTTPHeaderParameter("test", value: "a") diff --git a/Tests/MultipartFormDataTests/MediaTypeTests.swift b/Tests/MultipartFormDataTests/MediaTypeTests.swift index dc4e40d..1cde915 100644 --- a/Tests/MultipartFormDataTests/MediaTypeTests.swift +++ b/Tests/MultipartFormDataTests/MediaTypeTests.swift @@ -6,10 +6,12 @@ // import XCTest +#if canImport(UniformTypeIdentifiers) +import UniformTypeIdentifiers +#endif @testable import MultipartFormData final class MediaTypeTests: XCTestCase { - func testText() { let mediaType = MediaType(type: "type", subtype: "subtype") XCTAssertEqual(mediaType._text, "type/subtype") @@ -21,4 +23,21 @@ final class MediaTypeTests: XCTestCase { let expectedDescription = "type/subtype" XCTAssertEqual(mediaType.debugDescription, expectedDescription) } +#if canImport(UniformTypeIdentifiers) + + @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) + func testFromUTTypeConversion() throws { + let uniformType = try XCTUnwrap(UTType("public.comma-separated-values-text")) + let mediaType = try XCTUnwrap(MediaType(uniformType: uniformType)) + + XCTAssertEqual(mediaType, .textCsv) + } + + @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) + func testToUTTypeConversion() throws { + let uniformType = try XCTUnwrap(UTType(mediaType: .applicationJson)) + + XCTAssertEqual(uniformType.identifier, "public.json") + } +#endif } diff --git a/Tests/MultipartFormDataTests/MultipartFormDataTests.swift b/Tests/MultipartFormDataTests/MultipartFormDataTests.swift index 2dbd111..4a89670 100644 --- a/Tests/MultipartFormDataTests/MultipartFormDataTests.swift +++ b/Tests/MultipartFormDataTests/MultipartFormDataTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class MultipartFormDataTests: XCTestCase { - func testContentType() throws { let boundary = try Boundary(uncheckedBoundary: "test") let multipartFormData = MultipartFormData(boundary: boundary) diff --git a/Tests/MultipartFormDataTests/SubpartTests.swift b/Tests/MultipartFormDataTests/SubpartTests.swift index e7df384..8962458 100644 --- a/Tests/MultipartFormDataTests/SubpartTests.swift +++ b/Tests/MultipartFormDataTests/SubpartTests.swift @@ -9,7 +9,6 @@ import XCTest @testable import MultipartFormData final class SubpartTests: XCTestCase { - func testDataGeneration() throws { let subpart = Subpart( contentDisposition: ContentDisposition(name: "a"), diff --git a/Tests/MultipartFormDataTests/URLRequestTests.swift b/Tests/MultipartFormDataTests/URLRequestTests.swift index fa73084..d163e0c 100644 --- a/Tests/MultipartFormDataTests/URLRequestTests.swift +++ b/Tests/MultipartFormDataTests/URLRequestTests.swift @@ -12,7 +12,6 @@ import FoundationNetworking #endif final class URLRequestTests: XCTestCase { - func testFormDataInit() throws { let boundary = try Boundary(uncheckedBoundary: "test") let multipartFormData = MultipartFormData(boundary: boundary, body: [