Skip to content

Commit

Permalink
Fix a bug with throws on Encodable encoding nothing (#31)
Browse files Browse the repository at this point in the history
By encoding via `func encode(_:withRootKey:header:)` we always get an XML root node with label `rootKey`, so not encoding anything within `func encode(to:)` is fine in XML (unlike JSON).

* Fixed a bug that would cause `XMLEncoder` to throw on `Encodable`s encoding nothing
* Fix merge conflict
* Fix indentation and xcodeproj file
  • Loading branch information
regexident authored and MaxDesiatov committed Dec 21, 2018
1 parent 1f0cb9d commit 099272e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
24 changes: 12 additions & 12 deletions Sources/XMLCoder/Encoder/XMLEncoder.swift
Expand Up @@ -266,17 +266,17 @@ open class XMLEncoder {
encoder.nodeEncodings.append(options.nodeEncodingStrategy.nodeEncodings(forType: T.self, with: encoder))

let topLevel = try encoder.box(value)

let elementOrNone: _XMLElement?

if let keyed = topLevel as? KeyedBox {
elementOrNone = _XMLElement(key: rootKey, box: keyed)
} else if let unkeyed = topLevel as? UnkeyedBox {
elementOrNone = _XMLElement(key: rootKey, box: unkeyed)
} else {
fatalError("Unrecognized top-level element.")
}

guard let element = elementOrNone else {
throw EncodingError.invalidValue(value, EncodingError.Context(
codingPath: [],
Expand Down Expand Up @@ -379,7 +379,7 @@ class _XMLEncoder: Encoder {

extension _XMLEncoder: SingleValueEncodingContainer {
// MARK: - SingleValueEncodingContainer Methods

func assertCanEncodeNewValue() {
precondition(self.canEncodeNewValue, "Attempt to encode value through single value container when previously value already encoded.")
}
Expand Down Expand Up @@ -470,23 +470,23 @@ extension _XMLEncoder {
func box() -> SimpleBox {
return NullBox()
}

func box(_ value: Bool) -> SimpleBox {
return BoolBox(value)
}

func box(_ value: Decimal) -> SimpleBox {
return DecimalBox(value)
}

func box<T: BinaryInteger & SignedInteger & Encodable>(_ value: T) -> SimpleBox {
return IntBox(value)
}

func box<T: BinaryInteger & UnsignedInteger & Encodable>(_ value: T) -> SimpleBox {
return UIntBox(value)
}

func box<T: BinaryFloatingPoint & Encodable>(_ value: T) throws -> SimpleBox {
guard value.isInfinite || value.isNaN else {
return FloatBox(value)
Expand All @@ -506,7 +506,7 @@ extension _XMLEncoder {
func box(_ value: String) -> SimpleBox {
return StringBox(value)
}

func box(_ value: Date) throws -> Box {
switch options.dateEncodingStrategy {
case .deferredToDate:
Expand Down Expand Up @@ -550,8 +550,8 @@ extension _XMLEncoder {
func box(_ value: URL) -> SimpleBox {
return URLBox(value)
}
func box<T: Encodable>(_ value: T) throws -> Box {

internal func box<T: Encodable>(_ value: T) throws -> Box {
if T.self == Date.self || T.self == NSDate.self {
return try box(value as! Date)
} else if T.self == Data.self || T.self == NSData.self {
Expand Down
50 changes: 50 additions & 0 deletions Tests/XMLCoderTests/Minimal/EmptyTests.swift
@@ -0,0 +1,50 @@
//
// EmptyTests.swift
// XMLCoderTests
//
// Created by Vincent Esche on 12/19/18.
//

import XCTest
@testable import XMLCoder

class EmptyTests: XCTestCase {
struct Container: Codable, Equatable {
// empty

func encode(to encoder: Encoder) throws {
// do nothing
}
}

func testAttribute() throws {
let decoder = XMLDecoder()
let encoder = XMLEncoder()

encoder.nodeEncodingStrategy = .custom { codableType, _ in
return { _ in .attribute }
}

XCTAssertThrowsError(try decoder.decode(Container.self, from: Data()))

let encoded = try encoder.encode(Container(), withRootKey: "container")
XCTAssertEqual(String(data: encoded, encoding: .utf8)!, "<container />")
}

func testElement() throws {
let decoder = XMLDecoder()
let encoder = XMLEncoder()

encoder.outputFormatting = [.prettyPrinted]

XCTAssertThrowsError(try decoder.decode(Container.self, from: Data()))

let encoded = try encoder.encode(Container(), withRootKey: "container")
XCTAssertEqual(String(data: encoded, encoding: .utf8)!, "<container />")
}

static var allTests = [
("testAttribute", testAttribute),
("testElement", testElement),
]
}
6 changes: 6 additions & 0 deletions XMLCoder.xcodeproj/project.pbxproj
Expand Up @@ -25,6 +25,7 @@
BF63EF0621CD7A74001D38C5 /* URLBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63EF0521CD7A74001D38C5 /* URLBox.swift */; };
BF63EF0821CD7AF8001D38C5 /* URLBoxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63EF0721CD7AF8001D38C5 /* URLBoxTests.swift */; };
BF63EF0A21CD7C1A001D38C5 /* URLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63EF0921CD7C1A001D38C5 /* URLTests.swift */; };
BF63EF0C21CD7F28001D38C5 /* EmptyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63EF0B21CD7F28001D38C5 /* EmptyTests.swift */; };
BF9457A821CBB498005ACFDE /* NullBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF94579E21CBB497005ACFDE /* NullBox.swift */; };
BF9457A921CBB498005ACFDE /* KeyedBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF94579F21CBB497005ACFDE /* KeyedBox.swift */; };
BF9457AA21CBB498005ACFDE /* UnkeyedBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9457A021CBB497005ACFDE /* UnkeyedBox.swift */; };
Expand Down Expand Up @@ -113,6 +114,7 @@
BF63EF0521CD7A74001D38C5 /* URLBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBox.swift; sourceTree = "<group>"; };
BF63EF0721CD7AF8001D38C5 /* URLBoxTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBoxTests.swift; sourceTree = "<group>"; };
BF63EF0921CD7C1A001D38C5 /* URLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTests.swift; sourceTree = "<group>"; };
BF63EF0B21CD7F28001D38C5 /* EmptyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTests.swift; sourceTree = "<group>"; };
BF94579E21CBB497005ACFDE /* NullBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullBox.swift; sourceTree = "<group>"; };
BF94579F21CBB497005ACFDE /* KeyedBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyedBox.swift; sourceTree = "<group>"; };
BF9457A021CBB497005ACFDE /* UnkeyedBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnkeyedBox.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -263,6 +265,7 @@
BF9457E121CBB6BC005ACFDE /* Minimal */ = {
isa = PBXGroup;
children = (
BF63EF0B21CD7F28001D38C5 /* EmptyTests.swift */,
BF9457E221CBB6BC005ACFDE /* BoolTests.swift */,
BF9457E321CBB6BC005ACFDE /* IntTests.swift */,
BF9457E421CBB6BC005ACFDE /* NullTests.swift */,
Expand Down Expand Up @@ -340,7 +343,9 @@
OBJ_39 /* build */,
OBJ_40 /* Products */,
);
indentWidth = 4;
sourceTree = "<group>";
tabWidth = 4;
};
OBJ_7 /* Sources */ = {
isa = PBXGroup;
Expand Down Expand Up @@ -523,6 +528,7 @@
OBJ_83 /* CDTest.swift in Sources */,
OBJ_85 /* NodeEncodingStrategyTests.swift in Sources */,
OBJ_86 /* NoteTest.swift in Sources */,
BF63EF0C21CD7F28001D38C5 /* EmptyTests.swift in Sources */,
BF9457F721CBB6BC005ACFDE /* DataTests.swift in Sources */,
BF9457EE21CBB6BC005ACFDE /* IntTests.swift in Sources */,
OBJ_87 /* PlantCatalog.swift in Sources */,
Expand Down

0 comments on commit 099272e

Please sign in to comment.