From cf13a8af6b09c25605f340150bb6392ea9d3c0f8 Mon Sep 17 00:00:00 2001 From: Shannon Young Date: Fri, 28 Oct 2022 09:51:23 -0700 Subject: [PATCH] Move results into a different target --- .../AnswerResult.swift | 1 + .../AnswerType.swift | 1 + .../AssessmentResult.swift | 1 + .../BranchNodeResult.swift | 1 + .../CollectionResult.swift | 1 + .../ErrorResult.swift | 1 + .../FileArchivable.swift | 1 + .../FileResult.swift | 1 + Sources/ResultModel/Placeholder.swift | 1 - .../ResultData.swift | 1 + .../ResultDataFactory.swift | 3 +- .../ResultDataSerializer.swift | 1 + Tests/JsonModelTests/DocumentableTests.swift | 232 --------------- .../AnswerCodingInfoTests.swift | 3 +- .../AnswerResultObjectTests.swift | 3 +- .../ResultModelTests/DocumentableTests.swift | 277 ++++++++++++++++++ .../OrderedJSONEncoderTests.swift | 3 +- Tests/ResultModelTests/PlaceholderTests.swift | 28 -- .../ResultDataTests.swift | 3 +- 19 files changed, 297 insertions(+), 266 deletions(-) rename Sources/{JsonModel/ResultData => ResultModel}/AnswerResult.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/AnswerType.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/AssessmentResult.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/BranchNodeResult.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/CollectionResult.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/ErrorResult.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/FileArchivable.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/FileResult.swift (99%) delete mode 100644 Sources/ResultModel/Placeholder.swift rename Sources/{JsonModel/ResultData => ResultModel}/ResultData.swift (99%) rename Sources/{JsonModel/ResultData => ResultModel}/ResultDataFactory.swift (96%) rename Sources/{JsonModel/ResultData => ResultModel}/ResultDataSerializer.swift (99%) rename Tests/{JsonModelTests/ResultDataTests => ResultModelTests}/AnswerCodingInfoTests.swift (99%) rename Tests/{JsonModelTests/ResultDataTests => ResultModelTests}/AnswerResultObjectTests.swift (99%) create mode 100644 Tests/ResultModelTests/DocumentableTests.swift rename Tests/{JsonModelTests => ResultModelTests}/OrderedJSONEncoderTests.swift (99%) delete mode 100644 Tests/ResultModelTests/PlaceholderTests.swift rename Tests/{JsonModelTests/ResultDataTests => ResultModelTests}/ResultDataTests.swift (99%) diff --git a/Sources/JsonModel/ResultData/AnswerResult.swift b/Sources/ResultModel/AnswerResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/AnswerResult.swift rename to Sources/ResultModel/AnswerResult.swift index 65f1528..b4c0705 100644 --- a/Sources/JsonModel/ResultData/AnswerResult.swift +++ b/Sources/ResultModel/AnswerResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// An `AnswerResult` is used to hold a serializable answer to a question or measurement. This /// protocol is defined as a class to allow for mutating the `jsonValue` without requiring the diff --git a/Sources/JsonModel/ResultData/AnswerType.swift b/Sources/ResultModel/AnswerType.swift similarity index 99% rename from Sources/JsonModel/ResultData/AnswerType.swift rename to Sources/ResultModel/AnswerType.swift index e8f8473..f377732 100644 --- a/Sources/JsonModel/ResultData/AnswerType.swift +++ b/Sources/ResultModel/AnswerType.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// The coding information for an answer. This allows for adding custom information to the "kind" of question because /// JSON only supports a small subset of value types that are often encoded and can be described using JSON Schema diff --git a/Sources/JsonModel/ResultData/AssessmentResult.swift b/Sources/ResultModel/AssessmentResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/AssessmentResult.swift rename to Sources/ResultModel/AssessmentResult.swift index 87fdae0..4e3ba6e 100644 --- a/Sources/JsonModel/ResultData/AssessmentResult.swift +++ b/Sources/ResultModel/AssessmentResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// An ``AssessmentResult`` is the top-level ``ResultData`` for an assessment. public protocol AssessmentResult : BranchNodeResult { diff --git a/Sources/JsonModel/ResultData/BranchNodeResult.swift b/Sources/ResultModel/BranchNodeResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/BranchNodeResult.swift rename to Sources/ResultModel/BranchNodeResult.swift index fbb978e..1fd577e 100644 --- a/Sources/JsonModel/ResultData/BranchNodeResult.swift +++ b/Sources/ResultModel/BranchNodeResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// The ``BranchNodeResult`` is the result created for a given level of navigation of a node tree. The /// ``stepHistory`` is additive where each time a node is traversed, it is added to the list. diff --git a/Sources/JsonModel/ResultData/CollectionResult.swift b/Sources/ResultModel/CollectionResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/CollectionResult.swift rename to Sources/ResultModel/CollectionResult.swift index f492adc..eeaa4b4 100644 --- a/Sources/JsonModel/ResultData/CollectionResult.swift +++ b/Sources/ResultModel/CollectionResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// A `CollectionResult` is used to describe a collection of results. public protocol CollectionResult : AnyObject, ResultData, AnswerFinder { diff --git a/Sources/JsonModel/ResultData/ErrorResult.swift b/Sources/ResultModel/ErrorResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/ErrorResult.swift rename to Sources/ResultModel/ErrorResult.swift index bb890b7..5d2c01d 100644 --- a/Sources/JsonModel/ResultData/ErrorResult.swift +++ b/Sources/ResultModel/ErrorResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// `ErrorResult` is a result that holds information about an error. public protocol ErrorResult : ResultData { diff --git a/Sources/JsonModel/ResultData/FileArchivable.swift b/Sources/ResultModel/FileArchivable.swift similarity index 99% rename from Sources/JsonModel/ResultData/FileArchivable.swift rename to Sources/ResultModel/FileArchivable.swift index 7687ace..e289584 100644 --- a/Sources/JsonModel/ResultData/FileArchivable.swift +++ b/Sources/ResultModel/FileArchivable.swift @@ -31,6 +31,7 @@ // import Foundation +import JsonModel /// A data archive is a class object that can be used to add multiple files to a zipped archive for upload as /// a package. The data archive could also be a service that implements the logic for uploading results where diff --git a/Sources/JsonModel/ResultData/FileResult.swift b/Sources/ResultModel/FileResult.swift similarity index 99% rename from Sources/JsonModel/ResultData/FileResult.swift rename to Sources/ResultModel/FileResult.swift index 4946fdb..838a89f 100644 --- a/Sources/JsonModel/ResultData/FileResult.swift +++ b/Sources/ResultModel/FileResult.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// `FileResult` is a result that holds a pointer to a file url. public protocol FileResult : ResultData { diff --git a/Sources/ResultModel/Placeholder.swift b/Sources/ResultModel/Placeholder.swift deleted file mode 100644 index fecc4ab..0000000 --- a/Sources/ResultModel/Placeholder.swift +++ /dev/null @@ -1 +0,0 @@ -import Foundation diff --git a/Sources/JsonModel/ResultData/ResultData.swift b/Sources/ResultModel/ResultData.swift similarity index 99% rename from Sources/JsonModel/ResultData/ResultData.swift rename to Sources/ResultModel/ResultData.swift index c88e90d..d6ed33a 100644 --- a/Sources/JsonModel/ResultData/ResultData.swift +++ b/Sources/ResultModel/ResultData.swift @@ -31,6 +31,7 @@ // import Foundation +import JsonModel /// `ResultData` is the base protocol for an object that stores data. /// diff --git a/Sources/JsonModel/ResultData/ResultDataFactory.swift b/Sources/ResultModel/ResultDataFactory.swift similarity index 96% rename from Sources/JsonModel/ResultData/ResultDataFactory.swift rename to Sources/ResultModel/ResultDataFactory.swift index 00df6b1..5840247 100644 --- a/Sources/JsonModel/ResultData/ResultDataFactory.swift +++ b/Sources/ResultModel/ResultDataFactory.swift @@ -2,7 +2,7 @@ // ResultDataFactory.swift // // -// Copyright © 2020-2021 Sage Bionetworks. All rights reserved. +// Copyright © 2020-2022 Sage Bionetworks. All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// `ResultDataFactory` is a subclass of the `SerializationFactory` that registers a serializer /// for `JsonResultData` objects that can be used to deserialize the results. diff --git a/Sources/JsonModel/ResultData/ResultDataSerializer.swift b/Sources/ResultModel/ResultDataSerializer.swift similarity index 99% rename from Sources/JsonModel/ResultData/ResultDataSerializer.swift rename to Sources/ResultModel/ResultDataSerializer.swift index 0e72555..407df1c 100644 --- a/Sources/JsonModel/ResultData/ResultDataSerializer.swift +++ b/Sources/ResultModel/ResultDataSerializer.swift @@ -32,6 +32,7 @@ // import Foundation +import JsonModel /// `SerializableResultData` is the base implementation for `ResultData` that is serialized using diff --git a/Tests/JsonModelTests/DocumentableTests.swift b/Tests/JsonModelTests/DocumentableTests.swift index 5ef12f0..a14f97c 100644 --- a/Tests/JsonModelTests/DocumentableTests.swift +++ b/Tests/JsonModelTests/DocumentableTests.swift @@ -206,80 +206,6 @@ final class DocumentableTests: XCTestCase { XCTFail("Missing definition mapping for \(key)") } } - - func testResultDataFactory() { - do { - let factory = TestResultFactoryA() - let doc = JsonDocumentBuilder(factory: factory) - let schemas = try doc.buildSchemas() - - XCTAssertEqual(schemas.count, 4) - - if let testSchema = schemas.first(where: { $0.id.className == "TestResult"}), - let sampleDef = testSchema.definitions?["Sample"], - case .object(let sampleObj) = sampleDef, let sampleProps = sampleObj.properties { - XCTAssertNotNil(sampleProps["index"]) - XCTAssertNotNil(sampleProps["identifier"]) - XCTAssertNotNil(sampleProps["startDate"]) - } - else { - XCTFail("Failed to build schema.") - } - - if let rootSchema = schemas.first(where: { $0.id.className == "ResultData"}), - let def = rootSchema.definitions?["ResultObject"], - case .object(let obj) = def, let props = obj.properties { - XCTAssertNotNil(props["type"]) - XCTAssertNil(props["identifier"]) - XCTAssertNil(props["startDate"]) - XCTAssertNil(props["endDate"]) - } - else { - XCTFail("Failed to build schema.") - } - } - catch let err { - XCTFail("Failed to build the JsonSchema: \(err)") - } - } - - func testResultDataFactoryExternal() { - do { - let factory = TestResultFactoryB() - let doc = JsonDocumentBuilder(factory: factory) - let schemas = try doc.buildSchemas() - - let schemaNames = schemas.map { $0.id.className } - XCTAssertEqual(["TestResultExternal"], schemaNames) - - guard let schema = schemas.first, schema.id.className == "TestResultExternal" else { - XCTFail("Failed to build and filter schemas") - return - } - - if let interface = schema.root.allOf?.first?.refId { - XCTAssertEqual("ResultData", interface.className) - XCTAssertTrue(interface.isExternal) - XCTAssertEqual("https://sage-bionetworks.github.io/mobile-client-json/schemas/v2/ResultData.json", interface.classPath) - } - else { - XCTFail("Failed to add expected interfaces.") - } - - if let props = schema.root.properties, - let typeProp = props["type"], - case .const(let constType) = typeProp { - XCTAssertEqual("test", constType.const) - XCTAssertEqual("https://sage-bionetworks.github.io/mobile-client-json/schemas/v2/ResultData.json#SerializableResultType", constType.ref?.classPath) - } - else { - XCTFail("Failed to add expected property.") - } - } - catch let err { - XCTFail("Failed to build the JsonSchema: \(err)") - } - } } // MARK: Test objects @@ -437,163 +363,5 @@ extension AnotherB : DocumentableStruct { } } -class TestResultFactoryA : ResultDataFactory { - required init() { - super.init() - resultSerializer.add(TestResult()) - } -} - -extension SerializableResultType { - static let test: SerializableResultType = "test" -} - -struct TestResult : SerializableResultData, DocumentableStruct, DocumentableRootObject { - private enum CodingKeys : String, OrderedEnumCodingKey { - case serializableType="type", identifier, startDate, endDate, sample - } - - var serializableType: SerializableResultType = .test - var identifier: String = "test" - var startDate: Date = Date() - var endDate: Date = Date() - var sample: Sample = .init() - - func deepCopy() -> TestResult { - self - } - - public var jsonSchema: URL { - URL(string: "\(self.className).json", relativeTo: kSageJsonSchemaBaseURL)! - } - - public var documentDescription: String? { - "A result used to test root serialization." - } - - static func examples() -> [TestResult] { - [.init()] - } - - static func codingKeys() -> [CodingKey] { - CodingKeys.allCases - } - - static func isRequired(_ codingKey: CodingKey) -> Bool { - true - } - - static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { - guard let key = codingKey as? CodingKeys else { - throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") - } - switch key { - case .serializableType: - return .init(constValue: SerializableResultType.test) - case .identifier: - return .init(propertyType: .primitive(.string)) - case .startDate, .endDate: - return .init(propertyType: .format(.dateTime)) - case .sample: - return .init(propertyType: .reference(Sample.documentableType())) - } - } - - struct Sample : DocumentableStruct { - private enum CodingKeys : String, OrderedEnumCodingKey { - case index, identifier, startDate - } - - var index: Int = 0 - var identifier: String = "sample" - var startDate: Date = Date() - - static func examples() -> [Sample] { - [.init()] - } - - static func codingKeys() -> [CodingKey] { - CodingKeys.allCases - } - - static func isRequired(_ codingKey: CodingKey) -> Bool { - true - } - - static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { - guard let key = codingKey as? CodingKeys else { - throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") - } - switch key { - case .index: - return .init(propertyType: .primitive(.integer)) - case .identifier: - return .init(propertyType: .primitive(.string)) - case .startDate: - return .init(propertyType: .format(.dateTime)) - } - } - } -} - let testBURL = URL(string: "https://foo.org/schemas/")! -class TestResultFactoryB : ResultDataFactory { - required init() { - super.init() - resultSerializer.add(TestResultExternal()) - } - - override var jsonSchemaBaseURL: URL { - testBURL - } -} - -struct TestResultExternal : SerializableResultData, DocumentableStruct, DocumentableRootObject { - private enum CodingKeys : String, OrderedEnumCodingKey { - case serializableType="type", identifier, startDate, endDate - } - - var serializableType: SerializableResultType = .test - var identifier: String = "test" - var startDate: Date = Date() - var endDate: Date = Date() - - func deepCopy() -> TestResultExternal { - self - } - - public var jsonSchema: URL { - URL(string: "\(self.className).json", relativeTo: testBURL)! - } - - public var documentDescription: String? { - "A result used to test root serialization." - } - - static func examples() -> [TestResultExternal] { - [.init()] - } - - static func codingKeys() -> [CodingKey] { - CodingKeys.allCases - } - - static func isRequired(_ codingKey: CodingKey) -> Bool { - true - } - - static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { - guard let key = codingKey as? CodingKeys else { - throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") - } - switch key { - case .serializableType: - return .init(constValue: SerializableResultType.test) - case .identifier: - return .init(propertyType: .primitive(.string)) - case .startDate, .endDate: - return .init(propertyType: .format(.dateTime)) - } - } -} diff --git a/Tests/JsonModelTests/ResultDataTests/AnswerCodingInfoTests.swift b/Tests/ResultModelTests/AnswerCodingInfoTests.swift similarity index 99% rename from Tests/JsonModelTests/ResultDataTests/AnswerCodingInfoTests.swift rename to Tests/ResultModelTests/AnswerCodingInfoTests.swift index a71bd46..d7281af 100644 --- a/Tests/JsonModelTests/ResultDataTests/AnswerCodingInfoTests.swift +++ b/Tests/ResultModelTests/AnswerCodingInfoTests.swift @@ -31,7 +31,8 @@ // import XCTest -@testable import JsonModel +import JsonModel +@testable import ResultModel class AnswerTypeTests: XCTestCase { diff --git a/Tests/JsonModelTests/ResultDataTests/AnswerResultObjectTests.swift b/Tests/ResultModelTests/AnswerResultObjectTests.swift similarity index 99% rename from Tests/JsonModelTests/ResultDataTests/AnswerResultObjectTests.swift rename to Tests/ResultModelTests/AnswerResultObjectTests.swift index 6070ef2..cc18927 100644 --- a/Tests/JsonModelTests/ResultDataTests/AnswerResultObjectTests.swift +++ b/Tests/ResultModelTests/AnswerResultObjectTests.swift @@ -32,7 +32,8 @@ // import XCTest -@testable import JsonModel +import JsonModel +@testable import ResultModel class AnswerResultObjectTests: XCTestCase { diff --git a/Tests/ResultModelTests/DocumentableTests.swift b/Tests/ResultModelTests/DocumentableTests.swift new file mode 100644 index 0000000..2d595d1 --- /dev/null +++ b/Tests/ResultModelTests/DocumentableTests.swift @@ -0,0 +1,277 @@ +// +// DocumentableTests.swift +// +// +// Copyright © 2020-2022 Sage Bionetworks. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder(s) nor the names of any contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. No license is granted to the trademarks of +// the copyright holders even if such marks are included in this software. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +import XCTest +import JsonModel +@testable import ResultModel + +final class DocumentableTests: XCTestCase { + + + func testResultDataFactory() { + do { + let factory = TestResultFactoryA() + let doc = JsonDocumentBuilder(factory: factory) + let schemas = try doc.buildSchemas() + + XCTAssertEqual(schemas.count, 4) + + if let testSchema = schemas.first(where: { $0.id.className == "TestResult"}), + let sampleDef = testSchema.definitions?["Sample"], + case .object(let sampleObj) = sampleDef, let sampleProps = sampleObj.properties { + XCTAssertNotNil(sampleProps["index"]) + XCTAssertNotNil(sampleProps["identifier"]) + XCTAssertNotNil(sampleProps["startDate"]) + } + else { + XCTFail("Failed to build schema.") + } + + if let rootSchema = schemas.first(where: { $0.id.className == "ResultData"}), + let def = rootSchema.definitions?["ResultObject"], + case .object(let obj) = def, let props = obj.properties { + XCTAssertNotNil(props["type"]) + XCTAssertNil(props["identifier"]) + XCTAssertNil(props["startDate"]) + XCTAssertNil(props["endDate"]) + } + else { + XCTFail("Failed to build schema.") + } + } + catch let err { + XCTFail("Failed to build the JsonSchema: \(err)") + } + } + + func testResultDataFactoryExternal() { + do { + let factory = TestResultFactoryB() + let doc = JsonDocumentBuilder(factory: factory) + let schemas = try doc.buildSchemas() + + let schemaNames = schemas.map { $0.id.className } + XCTAssertEqual(["TestResultExternal"], schemaNames) + + guard let schema = schemas.first, schema.id.className == "TestResultExternal" else { + XCTFail("Failed to build and filter schemas") + return + } + + if let interface = schema.root.allOf?.first?.refId { + XCTAssertEqual("ResultData", interface.className) + XCTAssertTrue(interface.isExternal) + XCTAssertEqual("https://sage-bionetworks.github.io/mobile-client-json/schemas/v2/ResultData.json", interface.classPath) + } + else { + XCTFail("Failed to add expected interfaces.") + } + + if let props = schema.root.properties, + let typeProp = props["type"], + case .const(let constType) = typeProp { + XCTAssertEqual("test", constType.const) + XCTAssertEqual("https://sage-bionetworks.github.io/mobile-client-json/schemas/v2/ResultData.json#SerializableResultType", constType.ref?.classPath) + } + else { + XCTFail("Failed to add expected property.") + } + } + catch let err { + XCTFail("Failed to build the JsonSchema: \(err)") + } + } +} + +// MARK: Test objects + +class TestResultFactoryA : ResultDataFactory { + required init() { + super.init() + resultSerializer.add(TestResult()) + } +} + +extension SerializableResultType { + static let test: SerializableResultType = "test" +} + +struct TestResult : SerializableResultData, DocumentableStruct, DocumentableRootObject { + private enum CodingKeys : String, OrderedEnumCodingKey { + case serializableType="type", identifier, startDate, endDate, sample + } + + var serializableType: SerializableResultType = .test + var identifier: String = "test" + var startDate: Date = Date() + var endDate: Date = Date() + var sample: Sample = .init() + + func deepCopy() -> TestResult { + self + } + + public var jsonSchema: URL { + URL(string: "\(self.className).json", relativeTo: kSageJsonSchemaBaseURL)! + } + + public var documentDescription: String? { + "A result used to test root serialization." + } + + static func examples() -> [TestResult] { + [.init()] + } + + static func codingKeys() -> [CodingKey] { + CodingKeys.allCases + } + + static func isRequired(_ codingKey: CodingKey) -> Bool { + true + } + + static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { + guard let key = codingKey as? CodingKeys else { + throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") + } + switch key { + case .serializableType: + return .init(constValue: SerializableResultType.test) + case .identifier: + return .init(propertyType: .primitive(.string)) + case .startDate, .endDate: + return .init(propertyType: .format(.dateTime)) + case .sample: + return .init(propertyType: .reference(Sample.documentableType())) + } + } + + struct Sample : DocumentableStruct { + private enum CodingKeys : String, OrderedEnumCodingKey { + case index, identifier, startDate + } + + var index: Int = 0 + var identifier: String = "sample" + var startDate: Date = Date() + + static func examples() -> [Sample] { + [.init()] + } + + static func codingKeys() -> [CodingKey] { + CodingKeys.allCases + } + + static func isRequired(_ codingKey: CodingKey) -> Bool { + true + } + + static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { + guard let key = codingKey as? CodingKeys else { + throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") + } + switch key { + case .index: + return .init(propertyType: .primitive(.integer)) + case .identifier: + return .init(propertyType: .primitive(.string)) + case .startDate: + return .init(propertyType: .format(.dateTime)) + } + } + } +} + +let testBURL = URL(string: "https://foo.org/schemas/")! + +class TestResultFactoryB : ResultDataFactory { + required init() { + super.init() + resultSerializer.add(TestResultExternal()) + } + + override var jsonSchemaBaseURL: URL { + testBURL + } +} + +struct TestResultExternal : SerializableResultData, DocumentableStruct, DocumentableRootObject { + private enum CodingKeys : String, OrderedEnumCodingKey { + case serializableType="type", identifier, startDate, endDate + } + + var serializableType: SerializableResultType = .test + var identifier: String = "test" + var startDate: Date = Date() + var endDate: Date = Date() + + func deepCopy() -> TestResultExternal { + self + } + + public var jsonSchema: URL { + URL(string: "\(self.className).json", relativeTo: testBURL)! + } + + public var documentDescription: String? { + "A result used to test root serialization." + } + + static func examples() -> [TestResultExternal] { + [.init()] + } + + static func codingKeys() -> [CodingKey] { + CodingKeys.allCases + } + + static func isRequired(_ codingKey: CodingKey) -> Bool { + true + } + + static func documentProperty(for codingKey: CodingKey) throws -> DocumentProperty { + guard let key = codingKey as? CodingKeys else { + throw DocumentableError.invalidCodingKey(codingKey, "\(codingKey) is not recognized for this class") + } + switch key { + case .serializableType: + return .init(constValue: SerializableResultType.test) + case .identifier: + return .init(propertyType: .primitive(.string)) + case .startDate, .endDate: + return .init(propertyType: .format(.dateTime)) + } + } +} diff --git a/Tests/JsonModelTests/OrderedJSONEncoderTests.swift b/Tests/ResultModelTests/OrderedJSONEncoderTests.swift similarity index 99% rename from Tests/JsonModelTests/OrderedJSONEncoderTests.swift rename to Tests/ResultModelTests/OrderedJSONEncoderTests.swift index 099e46f..fda2788 100644 --- a/Tests/JsonModelTests/OrderedJSONEncoderTests.swift +++ b/Tests/ResultModelTests/OrderedJSONEncoderTests.swift @@ -31,7 +31,8 @@ // import XCTest -@testable import JsonModel +import JsonModel +@testable import ResultModel class OrderedJSONEncoderTests: XCTestCase { diff --git a/Tests/ResultModelTests/PlaceholderTests.swift b/Tests/ResultModelTests/PlaceholderTests.swift deleted file mode 100644 index 04cb85b..0000000 --- a/Tests/ResultModelTests/PlaceholderTests.swift +++ /dev/null @@ -1,28 +0,0 @@ -import XCTest - -final class PlaceholderTests: XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - // Any test you write for XCTest can be annotated as throws and async. - // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. - // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. - } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - self.measure { - // Put the code you want to measure the time of here. - } - } - -} diff --git a/Tests/JsonModelTests/ResultDataTests/ResultDataTests.swift b/Tests/ResultModelTests/ResultDataTests.swift similarity index 99% rename from Tests/JsonModelTests/ResultDataTests/ResultDataTests.swift rename to Tests/ResultModelTests/ResultDataTests.swift index 52da47e..5f0b008 100644 --- a/Tests/JsonModelTests/ResultDataTests/ResultDataTests.swift +++ b/Tests/ResultModelTests/ResultDataTests.swift @@ -31,7 +31,8 @@ // import XCTest -@testable import JsonModel +import JsonModel +@testable import ResultModel class ResultDataTests: XCTestCase {