mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Merge w/ master
This commit is contained in:
@@ -42,6 +42,8 @@ extension Validator {
|
||||
return value
|
||||
}
|
||||
|
||||
/// Validate the given value and then return it if valid.
|
||||
/// throws if invalid.
|
||||
public static func validate(_ value: To) throws -> To {
|
||||
let _ = try transform(value)
|
||||
return value
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// TransformerTests.swift
|
||||
//
|
||||
//
|
||||
// Created by Mathew Polzin on 8/2/19.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import JSONAPI
|
||||
import JSONAPITesting
|
||||
|
||||
class TransformerTests: XCTestCase {
|
||||
func testIdentityTransform() {
|
||||
let inString = "hello world"
|
||||
|
||||
XCTAssertNoThrow(try IdentityTransformer.transform(inString))
|
||||
XCTAssertEqual(inString, try? IdentityTransformer.transform(inString))
|
||||
|
||||
XCTAssertNoThrow(try IdentityTransformer.reverse(inString))
|
||||
XCTAssertEqual(inString, try? IdentityTransformer.reverse(inString))
|
||||
}
|
||||
|
||||
func testValidator() {
|
||||
let string1 = "hello"
|
||||
let string2 = "hello world"
|
||||
|
||||
XCTAssertThrowsError(try MoreThanFiveCharValidator.validate(string1))
|
||||
XCTAssertThrowsError(try MoreThanFiveCharValidator.transform(string1))
|
||||
XCTAssertThrowsError(try MoreThanFiveCharValidator.reverse(string1))
|
||||
|
||||
XCTAssertNoThrow(try MoreThanFiveCharValidator.validate(string2))
|
||||
XCTAssertNoThrow(try MoreThanFiveCharValidator.transform(string2))
|
||||
XCTAssertNoThrow(try MoreThanFiveCharValidator.reverse(string2))
|
||||
|
||||
XCTAssertEqual(string2, try MoreThanFiveCharValidator.transform(string2))
|
||||
XCTAssertEqual(string2, try MoreThanFiveCharValidator.reverse(string2))
|
||||
}
|
||||
}
|
||||
|
||||
enum MoreThanFiveCharValidator: Validator {
|
||||
public static func transform(_ value: String) throws -> String {
|
||||
guard value.count > 5 else {
|
||||
throw Error.fewerThanFiveChars
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
enum Error: Swift.Error {
|
||||
case fewerThanFiveChars
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
//
|
||||
// File.swift
|
||||
//
|
||||
//
|
||||
// Created by Mathew Polzin on 8/2/19.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import JSONAPI
|
||||
|
||||
class EmptyObjectDecoderTests: XCTestCase {
|
||||
func testEmptyStruct() {
|
||||
XCTAssertNoThrow(try EmptyStruct.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try EmptyStructWithCodingKeys.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testEmptyArray() {
|
||||
XCTAssertNoThrow(try [EmptyStruct].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [String].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Int].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Double].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Bool].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Float].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Int8].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Int16].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Int32].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [Int64].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [UInt].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [UInt8].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [UInt16].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [UInt32].init(from: EmptyObjectDecoder()))
|
||||
XCTAssertNoThrow(try [UInt64].init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testNonEmptyStruct() {
|
||||
XCTAssertThrowsError(try NonEmptyStruct<EmptyStruct>.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructString.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructInt.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructDouble.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructBool.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructFloat.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructInt8.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructInt16.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructInt32.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructInt64.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructUInt.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructUInt8.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructUInt16.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructUInt32.init(from: EmptyObjectDecoder()))
|
||||
XCTAssertThrowsError(try NonEmptyStructUInt64.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testWantingNil() {
|
||||
XCTAssertThrowsError(try StructWithNil.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testWantingSingleValue() {
|
||||
XCTAssertThrowsError(try StructWithSingleValue.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testWantingNestedKeyed() {
|
||||
XCTAssertThrowsError(try StructWithNestedKeyedCall.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testWantingNestedUnkeyed() {
|
||||
XCTAssertThrowsError(try StructWithNestedUnkeyedCall.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testWantsSuper() {
|
||||
XCTAssertThrowsError(try StructWithUnkeyedSuper.init(from: EmptyObjectDecoder()))
|
||||
|
||||
XCTAssertThrowsError(try StructWithKeyedSuper.init(from: EmptyObjectDecoder()))
|
||||
}
|
||||
|
||||
func testKeysAndCodingPath() {
|
||||
XCTAssertEqual(try? EmptyObjectDecoder().container(keyedBy: EmptyStructWithCodingKeys.CodingKeys.self).allKeys.count, 0)
|
||||
XCTAssertEqual(try? EmptyObjectDecoder().container(keyedBy: EmptyStructWithCodingKeys.CodingKeys.self).codingPath.count, 0)
|
||||
}
|
||||
}
|
||||
|
||||
struct EmptyStruct: Decodable {
|
||||
|
||||
}
|
||||
|
||||
struct EmptyStructWithCodingKeys: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {}
|
||||
}
|
||||
|
||||
struct NonEmptyStruct<T: Decodable>: Decodable {
|
||||
let value: T
|
||||
}
|
||||
|
||||
struct NonEmptyStructString: Decodable {
|
||||
let value: String
|
||||
}
|
||||
|
||||
struct NonEmptyStructInt: Decodable {
|
||||
let value: Int
|
||||
}
|
||||
|
||||
struct NonEmptyStructDouble: Decodable {
|
||||
let value: Double
|
||||
}
|
||||
|
||||
struct NonEmptyStructBool: Decodable {
|
||||
let value: Bool
|
||||
}
|
||||
|
||||
struct NonEmptyStructFloat: Decodable {
|
||||
let value: Float
|
||||
}
|
||||
|
||||
struct NonEmptyStructInt8: Decodable {
|
||||
let value: Int8
|
||||
}
|
||||
|
||||
struct NonEmptyStructInt16: Decodable {
|
||||
let value: Int16
|
||||
}
|
||||
|
||||
struct NonEmptyStructInt32: Decodable {
|
||||
let value: Int32
|
||||
}
|
||||
|
||||
struct NonEmptyStructInt64: Decodable {
|
||||
let value: Int64
|
||||
}
|
||||
|
||||
struct NonEmptyStructUInt: Decodable {
|
||||
let value: UInt
|
||||
}
|
||||
|
||||
struct NonEmptyStructUInt8: Decodable {
|
||||
let value: UInt8
|
||||
}
|
||||
|
||||
struct NonEmptyStructUInt16: Decodable {
|
||||
let value: UInt16
|
||||
}
|
||||
|
||||
struct NonEmptyStructUInt32: Decodable {
|
||||
let value: UInt32
|
||||
}
|
||||
|
||||
struct NonEmptyStructUInt64: Decodable {
|
||||
let value: UInt64
|
||||
}
|
||||
|
||||
struct StructWithNil: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let _ = try container.decodeNil(forKey: .hello)
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithSingleValue: Decodable {
|
||||
let value: String
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
value = try container.decode(String.self)
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithNestedKeyedCall: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
enum NestedKeys: String, CodingKey {
|
||||
case world
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let _ = try container.nestedContainer(keyedBy: NestedKeys.self, forKey: .hello)
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithNestedUnkeyedCall: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let _ = try container.nestedUnkeyedContainer(forKey: .hello)
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithUnkeyedSuper: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let _ = try decoder.container(keyedBy: CodingKeys.self).superDecoder()
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithKeyedSuper: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case hello
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let _ = try decoder.container(keyedBy: CodingKeys.self).superDecoder(forKey: .hello)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ extension APIDescriptionTests {
|
||||
static let __allTests__APIDescriptionTests = [
|
||||
("test_empty", test_empty),
|
||||
("test_failsMissingMeta", test_failsMissingMeta),
|
||||
("test_init", test_init),
|
||||
("test_NoDescriptionString", test_NoDescriptionString),
|
||||
("test_WithMeta", test_WithMeta),
|
||||
("test_WithVersion", test_WithVersion),
|
||||
@@ -172,6 +173,23 @@ extension DocumentTests {
|
||||
]
|
||||
}
|
||||
|
||||
extension EmptyObjectDecoderTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__EmptyObjectDecoderTests = [
|
||||
("testEmptyArray", testEmptyArray),
|
||||
("testEmptyStruct", testEmptyStruct),
|
||||
("testKeysAndCodingPath", testKeysAndCodingPath),
|
||||
("testNonEmptyStruct", testNonEmptyStruct),
|
||||
("testWantingNestedKeyed", testWantingNestedKeyed),
|
||||
("testWantingNestedUnkeyed", testWantingNestedUnkeyed),
|
||||
("testWantingNil", testWantingNil),
|
||||
("testWantingSingleValue", testWantingSingleValue),
|
||||
("testWantsSuper", testWantsSuper),
|
||||
]
|
||||
}
|
||||
|
||||
extension IncludedTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
@@ -393,6 +411,7 @@ extension ResourceObjectTests {
|
||||
("test_RleationshipsOfSameType", test_RleationshipsOfSameType),
|
||||
("test_RleationshipsOfSameType_encode", test_RleationshipsOfSameType_encode),
|
||||
("test_toMany_relationship_operator_access", test_toMany_relationship_operator_access),
|
||||
("test_toManyMetaRelationshipAccessWorks", test_toManyMetaRelationshipAccessWorks),
|
||||
("test_UnidentifiedEntity", test_UnidentifiedEntity),
|
||||
("test_UnidentifiedEntity_encode", test_UnidentifiedEntity_encode),
|
||||
("test_unidentifiedEntityAttributeAccess", test_unidentifiedEntityAttributeAccess),
|
||||
@@ -407,6 +426,16 @@ extension ResourceObjectTests {
|
||||
]
|
||||
}
|
||||
|
||||
extension TransformerTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__TransformerTests = [
|
||||
("testIdentityTransform", testIdentityTransform),
|
||||
("testValidator", testValidator),
|
||||
]
|
||||
}
|
||||
|
||||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(APIDescriptionTests.__allTests__APIDescriptionTests),
|
||||
@@ -415,6 +444,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
||||
testCase(ComputedPropertiesTests.__allTests__ComputedPropertiesTests),
|
||||
testCase(CustomAttributesTests.__allTests__CustomAttributesTests),
|
||||
testCase(DocumentTests.__allTests__DocumentTests),
|
||||
testCase(EmptyObjectDecoderTests.__allTests__EmptyObjectDecoderTests),
|
||||
testCase(IncludedTests.__allTests__IncludedTests),
|
||||
testCase(LinksTests.__allTests__LinksTests),
|
||||
testCase(NonJSONAPIRelatableTests.__allTests__NonJSONAPIRelatableTests),
|
||||
@@ -423,6 +453,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
||||
testCase(RelationshipTests.__allTests__RelationshipTests),
|
||||
testCase(ResourceBodyTests.__allTests__ResourceBodyTests),
|
||||
testCase(ResourceObjectTests.__allTests__ResourceObjectTests),
|
||||
testCase(TransformerTests.__allTests__TransformerTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user