diff --git a/Sources/OpenAPIKit/Path Item/PathItem.swift b/Sources/OpenAPIKit/Path Item/PathItem.swift index be003a5ec..684a5c48a 100644 --- a/Sources/OpenAPIKit/Path Item/PathItem.swift +++ b/Sources/OpenAPIKit/Path Item/PathItem.swift @@ -111,47 +111,7 @@ extension OpenAPI { trace = op } - public typealias Map = OrderedDictionary, PathItem>> - } -} - -extension Either where A == JSONReference, B == OpenAPI.PathItem { - public static func pathItem(_ pathItem: OpenAPI.PathItem) -> Self { - return .b(pathItem) - } - - public static func pathItem(summary: String? = nil, - description: String? = nil, - servers: [OpenAPI.Server]? = nil, - parameters: OpenAPI.PathItem.Parameter.Array = [], - get: OpenAPI.PathItem.Operation? = nil, - put: OpenAPI.PathItem.Operation? = nil, - post: OpenAPI.PathItem.Operation? = nil, - delete: OpenAPI.PathItem.Operation? = nil, - options: OpenAPI.PathItem.Operation? = nil, - head: OpenAPI.PathItem.Operation? = nil, - patch: OpenAPI.PathItem.Operation? = nil, - trace: OpenAPI.PathItem.Operation? = nil) -> Self { - return .b( - OpenAPI.PathItem( - summary: summary, - description: description, - servers: servers, - parameters: parameters, - get: get, - put: put, - post: post, - delete: delete, - options: options, - head: head, - patch: patch, - trace: trace - ) - ) - } - - public static func pathItem(reference: JSONReference) -> Self { - return .a(reference) + public typealias Map = OrderedDictionary } } @@ -224,7 +184,7 @@ extension OpenAPI.PathComponents: Decodable { let rawValue = try container.decode(String.self) - components = rawValue.split(separator: "/").map(String.init) + self.init(rawValue: rawValue) } } diff --git a/Tests/OpenAPIKitTests/DeclarativeEaseOfUseTests.swift b/Tests/OpenAPIKitTests/DeclarativeEaseOfUseTests.swift index 097c94e6b..5f4359bfd 100644 --- a/Tests/OpenAPIKitTests/DeclarativeEaseOfUseTests.swift +++ b/Tests/OpenAPIKitTests/DeclarativeEaseOfUseTests.swift @@ -33,7 +33,7 @@ final class DeclarativeEaseOfUseTests: XCTestCase { ) ], paths: [ - "/test/api/endpoint/{param}": .pathItem( + "/test/api/endpoint/{param}": .init( summary: "Test Endpoint", description: "Test Endpoint description", parameters: [ @@ -267,7 +267,7 @@ final class DeclarativeEaseOfUseTests: XCTestCase { info: apiInfo, servers: [server], paths: [ - "/test/api/endpoint/{param}": .pathItem(testRoute) + "/test/api/endpoint/{param}": testRoute ], components: components, security: [], diff --git a/Tests/OpenAPIKitTests/DocumentTests.swift b/Tests/OpenAPIKitTests/DocumentTests.swift index 91c6c3564..3914952f5 100644 --- a/Tests/OpenAPIKitTests/DocumentTests.swift +++ b/Tests/OpenAPIKitTests/DocumentTests.swift @@ -25,7 +25,7 @@ final class DocumentTests: XCTestCase { .init(url: URL(string: "https://google.com")!) ], paths: [ - "/hi/there": .pathItem( + "/hi/there": .init( parameters: [], get: .init( tags: "hi", @@ -278,7 +278,7 @@ extension DocumentTests { let document = OpenAPI.Document( info: .init(title: "API", version: "1.0"), servers: [], - paths: ["test": .pathItem(summary: "hi")], + paths: ["test": .init(summary: "hi")], components: .noComponents ) let encodedDocument = try testStringFromEncoding(of: document) @@ -325,7 +325,7 @@ extension DocumentTests { OpenAPI.Document( info: .init(title: "API", version: "1.0"), servers: [], - paths: ["test": .pathItem(summary: "hi")], + paths: ["test": .init(summary: "hi")], components: .noComponents ) ) diff --git a/Tests/OpenAPIKitTests/Path Item/PathItemTests.swift b/Tests/OpenAPIKitTests/Path Item/PathItemTests.swift index 01cef4479..402cf4e00 100644 --- a/Tests/OpenAPIKitTests/Path Item/PathItemTests.swift +++ b/Tests/OpenAPIKitTests/Path Item/PathItemTests.swift @@ -1,5 +1,5 @@ // -// File.swift +// PathItemTests.swift // // // Created by Mathew Polzin on 12/29/19. @@ -7,7 +7,446 @@ import XCTest import OpenAPIKit +import FineJSON final class PathItemTests: XCTestCase { - // TODO: write tests + func test_initializePathComponents() { + let t1 = OpenAPI.PathComponents(["hello", "world"]) + let t2 = OpenAPI.PathComponents(rawValue: "/hello/world") + let t3 = OpenAPI.PathComponents(rawValue: "hello/world") + let t4: OpenAPI.PathComponents = "/hello/world" + let t5: OpenAPI.PathComponents = "hello/world" + + XCTAssertEqual(t1, t2) + XCTAssertEqual(t2, t3) + XCTAssertEqual(t3, t4) + XCTAssertEqual(t4, t5) + + XCTAssertEqual(t1.rawValue, "/hello/world") + XCTAssertEqual(t2.rawValue, "/hello/world") + XCTAssertEqual(t3.rawValue, "/hello/world") + XCTAssertEqual(t4.rawValue, "/hello/world") + XCTAssertEqual(t5.rawValue, "/hello/world") + } + + func test_initializePathItem() { + // minimal + let _ = OpenAPI.PathItem() + + // maximal + let op = OpenAPI.PathItem.Operation(responses: [:]) + let _ = OpenAPI.PathItem( + summary: "summary", + description: "description", + servers: [OpenAPI.Server(url: URL(string: "http://google.com")!)], + parameters: [.parameter(name: "hello", parameterLocation: .query, schema: .string)], + get: op, + put: op, + post: op, + delete: op, + options: op, + head: op, + patch: op, + trace: op + ) + } + + func test_pathItemMutations() { + let op = OpenAPI.PathItem.Operation(responses: [:]) + + // adding/removing paths + var pathItem = OpenAPI.PathItem() + XCTAssertNil(pathItem.get) + XCTAssertNil(pathItem.put) + XCTAssertNil(pathItem.post) + XCTAssertNil(pathItem.delete) + XCTAssertNil(pathItem.options) + XCTAssertNil(pathItem.head) + XCTAssertNil(pathItem.patch) + XCTAssertNil(pathItem.trace) + + pathItem.get(op) + XCTAssertEqual(pathItem.get, op) + + pathItem.get(nil) + XCTAssertNil(pathItem.get) + + pathItem.put(op) + XCTAssertEqual(pathItem.put, op) + + pathItem.post(op) + XCTAssertEqual(pathItem.post, op) + + pathItem.delete(op) + XCTAssertEqual(pathItem.delete, op) + + pathItem.options(op) + XCTAssertEqual(pathItem.options, op) + + pathItem.head(op) + XCTAssertEqual(pathItem.head, op) + + pathItem.patch(op) + XCTAssertEqual(pathItem.patch, op) + + pathItem.trace(op) + XCTAssertEqual(pathItem.trace, op) + + // for/set/subscript + pathItem = .init() + XCTAssertNil(pathItem[.get]) + XCTAssertNil(pathItem[.put]) + XCTAssertNil(pathItem[.post]) + XCTAssertNil(pathItem[.delete]) + XCTAssertNil(pathItem[.options]) + XCTAssertNil(pathItem[.head]) + XCTAssertNil(pathItem[.patch]) + XCTAssertNil(pathItem[.trace]) + + pathItem[.get] = op + XCTAssertEqual(pathItem.for(.get), op) + + pathItem[.put] = op + XCTAssertEqual(pathItem.for(.put), op) + + pathItem[.post] = op + XCTAssertEqual(pathItem.for(.post), op) + + pathItem[.delete] = op + XCTAssertEqual(pathItem.for(.delete), op) + + pathItem[.options] = op + XCTAssertEqual(pathItem.for(.options), op) + + pathItem[.head] = op + XCTAssertEqual(pathItem.for(.head), op) + + pathItem[.patch] = op + XCTAssertEqual(pathItem.for(.patch), op) + + pathItem[.trace] = op + XCTAssertEqual(pathItem.for(.trace), op) + } + + func test_initializePathItemMap() { + let _: OpenAPI.PathItem.Map = [ + "hello/world": .init(), + ] + } +} + +// MARK: Codable Tests +extension PathItemTests { + func test_minimal_encode() throws { + let pathItem = OpenAPI.PathItem() + + let encodedPathItem = try testStringFromEncoding(of: pathItem) + + assertJSONEquivalent( + encodedPathItem, +""" +{ + +} +""" + ) + } + + func test_minimal_decode() throws { + let pathItemData = +""" +{ + +} +""".data(using: .utf8)! + + let pathItem = try testDecoder.decode(OpenAPI.PathItem.self, from: pathItemData) + + XCTAssertEqual(pathItem, OpenAPI.PathItem()) + } + + func test_meta_encode() throws { + let pathItem = OpenAPI.PathItem( + summary: "summary", + description: "description", + servers: [OpenAPI.Server(url: URL(string: "http://google.com")!)], + parameters: [.parameter(name: "hello", parameterLocation: .query, schema: .string)] + ) + + let encodedPathItem = try testStringFromEncoding(of: pathItem) + + assertJSONEquivalent( + encodedPathItem, +""" +{ + "description" : "description", + "parameters" : [ + { + "in" : "query", + "name" : "hello", + "schema" : { + "type" : "string" + } + } + ], + "servers" : [ + { + "url" : "http:\\/\\/google.com" + } + ], + "summary" : "summary" +} +""" + ) + } + + func test_meta_decode() throws { + let pathItemData = +""" +{ + "description" : "description", + "parameters" : [ + { + "in" : "query", + "name" : "hello", + "schema" : { + "type" : "string" + } + } + ], + "servers" : [ + { + "url" : "http:\\/\\/google.com" + } + ], + "summary" : "summary" +} +""".data(using: .utf8)! + + let pathItem = try testDecoder.decode(OpenAPI.PathItem.self, from: pathItemData) + + XCTAssertEqual( + pathItem, + OpenAPI.PathItem( + summary: "summary", + description: "description", + servers: [OpenAPI.Server(url: URL(string: "http://google.com")!)], + parameters: [.parameter(name: "hello", parameterLocation: .query, schema: .string(required: false))] + ) + ) + } + + func test_operations_encode() throws { + let op = OpenAPI.PathItem.Operation(responses: [:]) + + let pathItem = OpenAPI.PathItem( + get: op, + put: op, + post: op, + delete: op, + options: op, + head: op, + patch: op, + trace: op + ) + + let encodedPathItem = try testStringFromEncoding(of: pathItem) + + assertJSONEquivalent( + encodedPathItem, +""" +{ + "delete" : { + "responses" : { + + } + }, + "get" : { + "responses" : { + + } + }, + "head" : { + "responses" : { + + } + }, + "options" : { + "responses" : { + + } + }, + "patch" : { + "responses" : { + + } + }, + "post" : { + "responses" : { + + } + }, + "put" : { + "responses" : { + + } + }, + "trace" : { + "responses" : { + + } + } +} +""" + ) + } + + func test_operations_decode() throws { + let pathItemData = +""" +{ + "delete" : { + "responses" : { + + } + }, + "get" : { + "responses" : { + + } + }, + "head" : { + "responses" : { + + } + }, + "options" : { + "responses" : { + + } + }, + "patch" : { + "responses" : { + + } + }, + "post" : { + "responses" : { + + } + }, + "put" : { + "responses" : { + + } + }, + "trace" : { + "responses" : { + + } + } +} +""".data(using: .utf8)! + + let pathItem = try testDecoder.decode(OpenAPI.PathItem.self, from: pathItemData) + + let op = OpenAPI.PathItem.Operation(responses: [:]) + + XCTAssertEqual( + pathItem, + OpenAPI.PathItem( + get: op, + put: op, + post: op, + delete: op, + options: op, + head: op, + patch: op, + trace: op + ) + ) + } + + func test_pathComponents_encode() throws { + let test: [OpenAPI.PathComponents] = ["/hello/world", "hi/there"] + + let encodedTest = try testStringFromEncoding(of: test) + + assertJSONEquivalent( + encodedTest, +""" +[ + "\\/hello\\/world", + "\\/hi\\/there" +] +""" + ) + } + + func test_pathComponents_decode() throws { + let testData = +""" +[ + "\\/hello\\/world", + "\\/hi\\/there" +] +""".data(using: .utf8)! + + let test = try testDecoder.decode([OpenAPI.PathComponents].self, from: testData) + + XCTAssertEqual( + test, + [ + "/hello/world", + "hi/there" + ] + ) + } + + func test_pathItemMap_encode() throws { + let map: OpenAPI.PathItem.Map = [ + "/hello/world": .init(), + "hi/there": .init() + ] + + let encodedMap = try testStringFromEncoding(of: map) + + assertJSONEquivalent( + encodedMap, +""" +{ + "\\/hello\\/world" : { + + }, + "\\/hi\\/there" : { + + } +} +""" + ) + } + + func test_pathItemMap_decode() throws { + let mapData = +""" +{ + "\\/hello\\/world" : { + + }, + "\\/hi\\/there" : { + + } +} +""".data(using: .utf8)! + + let map = try FineJSONDecoder().decode(OpenAPI.PathItem.Map.self, from: mapData) + + XCTAssertEqual( + map, + [ + "/hello/world": .init(), + "/hi/there": .init() + ] + ) + } }