Skip to content

Commit

Permalink
Fix invalid [UnboxableByTransform] unboxing
Browse files Browse the repository at this point in the history
Before, the type was directly used, instead of applying the transform, when
an array of UnboxableByTransform types were being unboxed.

Resolves https://github.com/JohnSundell/Unbox/issues/106
  • Loading branch information
JohnSundell committed Aug 23, 2016
1 parent 93c9972 commit 43c38d1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
34 changes: 29 additions & 5 deletions Sources/Unbox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,15 @@ public class Unboxer {
}

/// Unbox a required Array of values that can be transformed into its final form
public func unbox<T: UnboxableByTransform>(key: String, isKeyPath: Bool = true) -> [T] {
return UnboxValueResolver<[T]>(self).resolveRequiredValueForKey(key, isKeyPath: isKeyPath, fallbackValue: [])
public func unbox<T: UnboxableByTransform>(key: String, isKeyPath: Bool = true, allowInvalidElements: Bool = false) -> [T] {
let transform = T.makeArrayTransformClosure(allowInvalidElements: allowInvalidElements)
return UnboxValueResolver<[T.UnboxRawValueType]>(self).resolveRequiredValueForKey(key, isKeyPath: isKeyPath, fallbackValue: [], transform: transform)
}

/// Unbox an optional Array of values that can be transformed into its final form
public func unbox<T: UnboxableByTransform>(key: String, isKeyPath: Bool = true) -> [T]? {
return UnboxValueResolver<[T]>(self).resolveOptionalValueForKey(key, isKeyPath: isKeyPath)
public func unbox<T: UnboxableByTransform>(key: String, isKeyPath: Bool = true, allowInvalidElements: Bool = false) -> [T]? {
let transform = T.makeArrayTransformClosure(allowInvalidElements: allowInvalidElements)
return UnboxValueResolver<[T.UnboxRawValueType]>(self).resolveOptionalValueForKey(key, isKeyPath: isKeyPath, transform: transform)
}

/// Unbox a required raw value from a certain index in a nested Array
Expand Down Expand Up @@ -603,7 +605,7 @@ public class Unboxer {
/// Unbox an optional Dictionary containing array of Unboxables
public func unbox<K: UnboxableKey, V: Unboxable>(key: String, isKeyPath: Bool = true, allowInvalidElements: Bool = false) -> [K : [V]]? {
return UnboxValueResolver<[String: [UnboxableDictionary]]>(self).resolveDictionaryValuesForKey(key, isKeyPath: isKeyPath, required: false, allowInvalidElements: allowInvalidElements) {
return try? Unbox($0, context: self.context, allowInvalidElements: allowInvalidElements)
return try? Unbox($0, context: self.context, allowInvalidElements: allowInvalidElements)
}
}

Expand Down Expand Up @@ -924,6 +926,28 @@ private extension UnboxableWithContext {
}
}

private extension UnboxableByTransform {
static func makeArrayTransformClosure(allowInvalidElements allowInvalidElements: Bool) -> ([UnboxRawValueType]) -> [Self]? {
return {
if allowInvalidElements {
return $0.flatMap { Self.transformUnboxedValue($0) }
}

var transformedValues = [Self]()

for rawValue in $0 {
guard let transformedvalue = Self.transformUnboxedValue(rawValue) else {
return nil
}

transformedValues.append(transformedvalue)
}

return transformedValues
}
}
}

private extension Unboxer {
static func unboxer(from data: NSData, context: Any?) throws -> Unboxer {
do {
Expand Down
28 changes: 27 additions & 1 deletion Tests/UnboxTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,33 @@ class UnboxTests: XCTestCase {
XCTAssertTrue(unboxed.bool3)
XCTAssertEqual(unboxed.double, Double(27))
XCTAssertEqual(unboxed.float, Float(39))
XCTAssertNil(unboxed.string)
XCTAssertEqual(unboxed.string, "7")
} catch {
XCTFail("\(error)")
}
}

func testArrayOfURLs() {
struct Model: Unboxable {
let optional: [NSURL]?
let required: [NSURL]

init(unboxer: Unboxer) {
self.optional = unboxer.unbox("optional")
self.required = unboxer.unbox("required")
}
}

let dictionary: UnboxableDictionary = [
"optional" : ["https://www.google.com"],
"required" : ["https://github.com/johnsundell/unbox"]
]

do {
let unboxed: Model = try Unbox(dictionary)
XCTAssertEqual(unboxed.optional?.count, 1)
XCTAssertEqual(unboxed.optional?.first, NSURL(string: "https://www.google.com"))
XCTAssertEqual(unboxed.required, [NSURL(string: "https://github.com/johnsundell/unbox")!])
} catch {
XCTFail("\(error)")
}
Expand Down

0 comments on commit 43c38d1

Please sign in to comment.