Skip to content

Commit

Permalink
Add missing overloads and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Anviking committed Jul 19, 2015
1 parent 3a3affa commit 46be066
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 112 deletions.
12 changes: 9 additions & 3 deletions Decodable.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
17FB81011B530FED0012F106 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17FB80F71B530FED0012F106 /* Decodable.framework */; };
17FB810E1B5311840012F106 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; };
17FB810F1B5311870012F106 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; };
8F4B52651B5BAA5700FDCBA7 /* ArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */; };
8F4B52661B5BAA5700FDCBA7 /* ArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */; };
8F87BCBB1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; };
8F87BCBC1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; };
8F87BCC41B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; };
8F87BCC51B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; };
8F87BCC11B58643200E53A8C /* PlsFixSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC01B58643200E53A8C /* PlsFixSwift.swift */; };
8F87BCC21B58643200E53A8C /* PlsFixSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC01B58643200E53A8C /* PlsFixSwift.swift */; };
8F87BCC41B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; };
8F87BCC51B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; };
8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; };
8FE7B5661B4C9FB900837609 /* Decodable.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FE7B5651B4C9FB900837609 /* Decodable.h */; settings = {ATTRIBUTES = (Public, ); }; };
8FE7B56D1B4C9FB900837609 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8FE7B5621B4C9FB900837609 /* Decodable.framework */; };
Expand Down Expand Up @@ -58,9 +60,10 @@
/* Begin PBXFileReference section */
17FB80F71B530FED0012F106 /* Decodable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Decodable.framework; sourceTree = BUILT_PRODUCTS_DIR; };
17FB81001B530FED0012F106 /* DecodableTests-Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DecodableTests-Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = "<group>"; };
8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorPathTests.swift; sourceTree = "<group>"; };
8F87BCC31B592F0E00E53A8C /* DecodingError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodingError.swift; sourceTree = "<group>"; };
8F87BCC01B58643200E53A8C /* PlsFixSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlsFixSwift.swift; sourceTree = "<group>"; };
8F87BCC31B592F0E00E53A8C /* DecodingError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodingError.swift; sourceTree = "<group>"; };
8F956D1E1B4D6FF700243072 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
8FE7B5621B4C9FB900837609 /* Decodable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Decodable.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8FE7B5651B4C9FB900837609 /* Decodable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decodable.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -152,6 +155,7 @@
8FE7B5711B4C9FB900837609 /* DecodableTests.swift */,
FF00609D1B5454F400D8CB77 /* DecodableExtensionTests.swift */,
FF0060AF1B546FB100D8CB77 /* DecodableOperatorsTests.swift */,
8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */,
8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */,
FFE77E1E1B5391AD00E52F28 /* Repository.swift */,
8FE7B5731B4C9FB900837609 /* Info.plist */,
Expand Down Expand Up @@ -365,6 +369,7 @@
8F87BCBC1B580CE200E53A8C /* ErrorPathTests.swift in Sources */,
FF00609F1B5454F400D8CB77 /* DecodableExtensionTests.swift in Sources */,
FF0060B11B546FB100D8CB77 /* DecodableOperatorsTests.swift in Sources */,
8F4B52661B5BAA5700FDCBA7 /* ArrayTests.swift in Sources */,
FFE77E211B5396FB00E52F28 /* Repository.swift in Sources */,
FF0060981B5453C600D8CB77 /* DecodableTests.swift in Sources */,
);
Expand All @@ -388,6 +393,7 @@
8F87BCBB1B580CE200E53A8C /* ErrorPathTests.swift in Sources */,
FF00609E1B5454F400D8CB77 /* DecodableExtensionTests.swift in Sources */,
FF0060B01B546FB100D8CB77 /* DecodableOperatorsTests.swift in Sources */,
8F4B52651B5BAA5700FDCBA7 /* ArrayTests.swift in Sources */,
8FE7B5721B4C9FB900837609 /* DecodableTests.swift in Sources */,
FFE77E221B5396FC00E52F28 /* Repository.swift in Sources */,
);
Expand Down
6 changes: 6 additions & 0 deletions Decodable/Decodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ public protocol Decodable {
static func decode(json: AnyObject) throws -> Self
}

public protocol MetaDecodable {
typealias MetaType
var objects: MetaType {get}
static func decode(json: AnyObject, type: Decodable.Type) throws -> MetaType
}

public protocol Castable: Decodable {}
extension Castable {
public static func decode(j: AnyObject) throws -> Self {
Expand Down
20 changes: 14 additions & 6 deletions Decodable/Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ private func catchErrorAndAppendPath<T>(path: String, block: ((AnyObject) throws
}
}

private func catchErrorAndSetRootObject<T>(object: AnyObject, block: (Void throws -> T)) throws -> T {
do {
return try block()
} catch var error as DecodingError {
error.info.rootObject = object
throw error
}
}

// MARK: Operators

// Middle
Expand Down Expand Up @@ -66,7 +75,9 @@ public func => <T>(lhs: AnyObject, rhs: ((AnyObject) throws -> T)) throws -> T

public func => <T: Decodable>(lhs: AnyObject, rhs: String) throws -> T
{
return try T.decode(parse(lhs, key: rhs))
return try catchErrorAndSetRootObject(lhs) {
try T.decode(parse(lhs, key: rhs))
}
}

// MARK: Optionals
Expand All @@ -80,12 +91,10 @@ public func => <T: Decodable>(lhs: AnyObject, rhs: String) -> T?
}
}

// MARK: Optional Arrays

public func => <T: Decodable>(lhs: AnyObject, rhs: String) -> [T]?
public func => <T>(lhs: AnyObject, rhs: ((AnyObject) throws -> T)) throws -> T?
{
do {
return try lhs => rhs as [T]
return try rhs(lhs)
} catch {
return nil
}
Expand All @@ -103,7 +112,6 @@ public func => (lhs: AnyObject, rhs: ((AnyObject) throws -> [String: AnyObject])
return try JSONDictionary.decode(rhs(lhs))
}


private func printArrayError(error: DecodingError) {
print("Error caught in nil-filtering Array Decoder (=>?): \(error)")
}
34 changes: 31 additions & 3 deletions Decodable/PlsFixSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,42 @@ public struct NilFilteringArray<T: Decodable>: Decodable {
}
}



public func => <T: Decodable>(lhs: AnyObject, rhs: String) throws -> [T]
{
return try ((lhs => rhs) as DecodableArray<T>).value
}


public func =>? <T: Decodable>(lhs: AnyObject, rhs: String) throws -> [T]
{
return try ((lhs => rhs) as NilFilteringArray<T>).value
}
}

public func => <T: Decodable>(lhs: AnyObject, rhs: ((AnyObject) throws -> DecodableArray<T>)) throws -> [T]
{
return try (rhs(lhs) as DecodableArray<T>).value
}

public func =>? <T: Decodable>(lhs: AnyObject, rhs: ((AnyObject) throws -> NilFilteringArray<T>)) throws -> [T]
{
return try (rhs(lhs) as NilFilteringArray<T>).value
}

// Optionals

public func => <T: Decodable>(lhs: AnyObject, rhs: String) -> [T]? {
do {
return try ((lhs => rhs) as DecodableArray<T>).value
} catch {
return nil
}
}

public func => <T: Decodable>(lhs: AnyObject, rhs: ((AnyObject) throws -> DecodableArray<T>)) -> [T]?
{
do {
return try (rhs(lhs) as DecodableArray<T>).value
} catch {
return nil
}
}
135 changes: 135 additions & 0 deletions DecodableTests/ArrayTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//
// ArrayTests.swift
// Decodable
//
// Created by Johannes Lund on 2015-07-19.
// Copyright © 2015 anviking. All rights reserved.
//

import XCTest
@testable import Decodable

class DecodableArrayTests: XCTestCase {

func testDecodeAnyDecodableArraySuccess() {
// given
let key = "key"
let value: NSArray = ["value1", "value2", "value3"]
let dictionary: NSDictionary = [key: value]
// when
let result = try! dictionary => key as Array<String>
// then
XCTAssertEqual(result, value)
}

func testDecodeNestedDecodableArraySuccess() {
// given
let key = "key"
let value: NSArray = ["value1", "value2", "value3"]
let dictionary: NSDictionary = [key: [key: value]]
// when
let result = try! dictionary => key => key as Array<String>
// then
XCTAssertEqual(result, value)
}

func testDecodeAnyDecodableOptionalArraySuccess() {
// given
let key = "key"
let value = ["value"]
let dictionary: NSDictionary = [key: value]
// when
let string = dictionary => key as [String]?
// then
XCTAssertEqual(string!, value)
}

func testDecodeAnyDecodableNestedOptionalArraySuccess() {
// given
let key = "key"
let value = ["value"]
let dictionary: NSDictionary = [key: [key: value]]
// when
let string = dictionary => key => key as [String]?
// then
XCTAssertEqual(string!, value)
}

func testDecodeAnyDecodableOptionalArrayNilSuccess() {
// given
let key = "key"
let dictionary: NSDictionary = [key: NSNull()]
// when
let string = dictionary => key as [String]?
// then
XCTAssertNil(string)
}

func testDecodeAnyDecodableOptionalArrayMissingKeySuccess() {
// given
let key = "key"
let dictionary = NSDictionary()
// when
let string = dictionary => key as [String]?
// then
XCTAssertNil(string)
}


// MARK: =>?

func testDecodeSafeArraySuccess() {
// given
let key = "key"
let value = ["A", "B", "C"]
let dictionary: NSDictionary = [key: value]
// when
let string = try! dictionary =>? key as [String]
// then
XCTAssertEqual(string, value)
}

func testDecodeSafeArrayCatchTypeExceptionMismatch() {
// given
let key = "key"
let value = ["A", 2, "B"]
let dictionary: NSDictionary = [key: value]
// when
let string = try! dictionary =>? key as [String]
// then
XCTAssertEqual(string, ["A", "B"])
}

func testDecodeSafeArrayCatchTypeMismatchExceptionInObjects() {
// given
let key = "key"
let value = [["id": "007", "login": "mradams"], ["id": 1, "login": "jenglish"]]
let dictionary: NSDictionary = [key: value]
// when
let array = try! dictionary =>? key as [Owner]
// then
XCTAssertEqual(array, [Owner(id: 1, login: "jenglish")])
}

func testDecodeSafeArrayCatchJSONNotObjectException() {
// given
let key = "key"
let value = [["id": 7, "login": "mradams"], 2]
let dictionary: NSDictionary = [key: value]
// when
let array = try! dictionary =>? key as [Owner]
// then
XCTAssertEqual(array, [Owner(id: 7, login: "mradams")])
}

func testDecodeSafeArrayCatchMissingKeyException() {
// given
let key = "key"
let value = [["login": "mradams"], ["id": 1, "login": "jenglish"]]
let dictionary: NSDictionary = [key: value]
// when
let array = try! dictionary =>? key as [Owner]
// then
XCTAssertEqual(array, [Owner(id: 1, login: "jenglish")])
}
}
Loading

0 comments on commit 46be066

Please sign in to comment.