Skip to content

Commit

Permalink
Define encode/decode in terms of NSDictionary.
Browse files Browse the repository at this point in the history
Added more tests.
  • Loading branch information
samdeane committed Feb 20, 2018
1 parent 2827368 commit 4a7966c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Sources/DictionaryCoding/DictionaryDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ open class DictionaryDecoder {
/// - returns: A value of the requested type.
/// - throws: `DecodingError.dataCorrupted` if values requested from the payload are corrupted, or if the given data is not valid Dictionary.
/// - throws: An error if any value throws an error during decoding.
open func decode<T : Decodable>(_ type: T.Type, from dictionary: [String:Any]) throws -> T {
open func decode<T : Decodable>(_ type: T.Type, from dictionary: NSDictionary) throws -> T {
let decoder = _DictionaryDecoder(referencing: dictionary, options: self.options)
guard let value = try decoder.unbox(dictionary, as: type) else {
throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value."))
Expand Down
4 changes: 2 additions & 2 deletions Sources/DictionaryCoding/DictionaryEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ open class DictionaryEncoder {
/// - returns: A new `Data` value containing the encoded Dictionary data.
/// - throws: `EncodingError.invalidValue` if a non-conforming floating-point value is encountered during encoding, and the encoding strategy is `.throw`.
/// - throws: An error if any value throws an error during encoding.
open func encode<T : Encodable>(_ value: T) throws -> [String:Any] {
open func encode<T : Encodable>(_ value: T) throws -> NSDictionary {
let encoder = _DictionaryEncoder(options: self.options)

guard let topLevel = try encoder.box_(value) else {
Expand All @@ -211,7 +211,7 @@ open class DictionaryEncoder {
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) encoded as string Dictionary fragment."))
}

return topLevel as! [String:Any]
return topLevel as! NSDictionary
}
}

Expand Down
68 changes: 58 additions & 10 deletions Tests/DictionaryCodingTests/DictionaryCodingTests.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,71 @@
import XCTest
@testable import DictionaryCoding

struct Test : Codable {
struct Pet : Codable {
let name : String
}

struct Person : Codable {
let name : String
let age : Int
let pets : [Pet]
}

class DictionaryCodingTests: XCTestCase {
func testExample() throws {
let test = Test(name: "Brad")

func testEncoding() throws {
let test = Person(name: "Sam", age: 48, pets:[Pet(name: "Morven"), Pet(name: "Rebus")])
let encoder = DictionaryEncoder()
let encoded = try encoder.encode(test)
print("\(encoded)")

let decoder = DictionaryDecoder()
let decoded = try decoder.decode(Test.self, from: encoded)
print("\(decoded)")
XCTAssertEqual(encoded["name"] as? String, "Sam")
XCTAssertEqual(encoded["age"] as? Int, 48)
}

static var allTests = [
("testExample", testExample),
func testDecodingNSDictionary() throws {
let pet1 : NSMutableDictionary = NSMutableDictionary()
pet1["name"] = "Morven"
let pet2 : NSMutableDictionary = NSMutableDictionary()
pet2["name"] = "Rebus"
let pets : NSMutableArray = NSMutableArray()
pets.add(pet1)
pets.add(pet2)
let dict : NSMutableDictionary = NSMutableDictionary()
dict["name"] = "Sam"
dict["age"] = 48
dict["pets"] = pets

let decoder = DictionaryDecoder()
let decoded = try decoder.decode(Person.self, from: dict)

XCTAssertEqual(decoded.name, "Sam")
XCTAssertEqual(decoded.age, 48)
XCTAssertEqual(decoded.pets.count, 2)
XCTAssertEqual(decoded.pets[0].name, "Morven")
XCTAssertEqual(decoded.pets[1].name, "Rebus")
}

func testDecodingCFDictionary() throws {
let dict = [ "name" : "Sam", "age" : 48, "pets" : [ ["name" : "Morven"], ["name" : "Rebus"]]] as CFDictionary

let decoder = DictionaryDecoder()
let decoded = try decoder.decode(Person.self, from: dict)

XCTAssertEqual(decoded.name, "Sam")
XCTAssertEqual(decoded.age, 48)
XCTAssertEqual(decoded.pets.count, 2)
XCTAssertEqual(decoded.pets[0].name, "Morven")
XCTAssertEqual(decoded.pets[1].name, "Rebus")
}

func testFailureWithMissingKeys() {
let dict = [ "name" : "Sam", "age" : 48 ] as NSDictionary
let decoder = DictionaryDecoder()
XCTAssertThrowsError(try decoder.decode(Person.self, from: dict))
}

static var allTests = [
("testEncoding", testEncoding),
("testDecodingNSDictionary", testDecodingNSDictionary),
("testDecodingCFDictionary", testDecodingCFDictionary),
]
}

0 comments on commit 4a7966c

Please sign in to comment.