Skip to content

Commit d24ff75

Browse files
committed
added tests for new behaviour
1 parent f52f198 commit d24ff75

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

Sources/XMLCoder/Encoder/XMLEncoder.swift

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ open class XMLEncoder {
293293
let keyEncodingStrategy: KeyEncodingStrategy
294294
let nodeEncodingStrategy: NodeEncodingStrategy
295295
let stringEncodingStrategy: StringEncodingStrategy
296+
let rootAttributes: [String: String]
296297
let userInfo: [CodingUserInfoKey: Any]
297298
}
298299

@@ -304,9 +305,12 @@ open class XMLEncoder {
304305
keyEncodingStrategy: keyEncodingStrategy,
305306
nodeEncodingStrategy: nodeEncodingStrategy,
306307
stringEncodingStrategy: stringEncodingStrategy,
308+
rootAttributes: rootAttributes,
307309
userInfo: userInfo)
308310
}
309311

312+
public var rootAttributes: [String: String] = [:]
313+
310314
// MARK: - Constructing a XML Encoder
311315

312316
/// Initializes `self` with default strategies.
@@ -326,7 +330,7 @@ open class XMLEncoder {
326330
/// - throws: An error if any value throws an error during encoding.
327331
open func encode<T: Encodable>(_ value: T,
328332
withRootKey rootKey: String? = nil,
329-
rootAttributes: [String: String],
333+
rootAttributes: [String: String]? = nil,
330334
header: XMLHeader? = nil) throws -> Data {
331335
let encoder = XMLEncoderImplementation(
332336
options: options,
@@ -335,11 +339,11 @@ open class XMLEncoder {
335339
encoder.nodeEncodings.append(options.nodeEncodingStrategy.nodeEncodings(forType: T.self, with: encoder))
336340

337341
let topLevel = try encoder.box(value)
338-
let attributes = rootAttributes.map(Attribute.init)
342+
let attributes = rootAttributes?.map(Attribute.init) ?? []
339343

340344
let elementOrNone: XMLCoderElement?
341345

342-
let rootKey = rootKey ?? "\(T.self)"
346+
let rootKey = rootKey ?? "\(T.self)".convert(for: keyEncodingStrategy)
343347

344348
if let keyedBox = topLevel as? KeyedBox {
345349
elementOrNone = XMLCoderElement(key: rootKey, box: keyedBox, attributes: attributes)
@@ -365,3 +369,24 @@ open class XMLEncoder {
365369
.data(using: .utf8, allowLossyConversion: true)!
366370
}
367371
}
372+
373+
private extension String {
374+
func convert(for encodingStrategy: XMLEncoder.KeyEncodingStrategy) -> String {
375+
switch encodingStrategy {
376+
case .useDefaultKeys:
377+
return self
378+
case .convertToSnakeCase:
379+
return XMLEncoder.KeyEncodingStrategy._convertToSnakeCase(self)
380+
case .convertToKebabCase:
381+
return XMLEncoder.KeyEncodingStrategy._convertToKebabCase(self)
382+
case let .custom(converter):
383+
return self
384+
case .capitalized:
385+
return XMLEncoder.KeyEncodingStrategy._convertToCapitalized(self)
386+
case .uppercased:
387+
return XMLEncoder.KeyEncodingStrategy._convertToUppercased(self)
388+
case .lowercased:
389+
return XMLEncoder.KeyEncodingStrategy._convertToLowercased(self)
390+
}
391+
}
392+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// RootLevetExtraAttributesTests.swift
3+
// XMLCoderTests
4+
//
5+
// Created by Luís Portela Afonso on 19/03/2020.
6+
//
7+
8+
import XCTest
9+
@testable import XMLCoder
10+
11+
class RootLevetExtraAttributesTests: XCTestCase {
12+
13+
private let encoder = XMLEncoder()
14+
15+
func testExtraAttributes() {
16+
let policy = Policy(name: "test", initial: "extra root attributes")
17+
18+
let extraRootAttributes = [
19+
"xmlns" : "http://www.nrf-arts.org/IXRetail/namespace",
20+
"xmlns:xsd" : "http://www.w3.org/2001/XMLSchema",
21+
"xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance"
22+
]
23+
24+
encoder.keyEncodingStrategy = .lowercased
25+
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
26+
27+
do {
28+
let data = try encoder.encode(policy,
29+
rootAttributes: extraRootAttributes)
30+
31+
let dataString = String(data: data, encoding: .utf8)
32+
XCTAssertNotNil(dataString, "failed to encode object")
33+
34+
let expected = """
35+
<policy name="test" xmlns="http://www.nrf-arts.org/IXRetail/namespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
36+
<initial>extra root attributes</initial>
37+
</policy>
38+
"""
39+
40+
XCTAssertEqual(dataString!, expected, "")
41+
} catch {
42+
XCTAssertThrowsError(error)
43+
}
44+
}
45+
}
46+
47+
private struct Policy: Encodable, DynamicNodeEncoding {
48+
var name: String
49+
var initial: String
50+
51+
enum CodingKeys: String, CodingKey {
52+
case name, initial//, rule
53+
}
54+
55+
static func nodeEncoding(for key: CodingKey) -> XMLEncoder.NodeEncoding {
56+
switch key {
57+
case Policy.CodingKeys.name: return .attribute
58+
default: return .element
59+
}
60+
}
61+
}

XMLCoder.xcodeproj/project.pbxproj

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
/* Begin PBXBuildFile section */
2424
07E441BA2340F14B00890F46 /* EmptyElementEmptyStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E441B92340F14B00890F46 /* EmptyElementEmptyStringTests.swift */; };
2525
4A062D4F2341924E009BCAC1 /* CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A062D4E2341924E009BCAC1 /* CombineTests.swift */; };
26+
970FA9DC2422EFAE0023C1EC /* RootLevetExtraAttributesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970FA9DB2422EFAE0023C1EC /* RootLevetExtraAttributesTests.swift */; };
2627
B54555BC2343F5C1000D4128 /* EmptyArrayTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54555BB2343F5C1000D4128 /* EmptyArrayTest.swift */; };
2728
B5E67533238B47E5006C8548 /* MixedChoiceAndNonChoiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E67532238B47E5006C8548 /* MixedChoiceAndNonChoiceTests.swift */; };
2829
B5E67535238B4960006C8548 /* IntOrString.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E67534238B4960006C8548 /* IntOrString.swift */; };
@@ -164,6 +165,7 @@
164165
/* Begin PBXFileReference section */
165166
07E441B92340F14B00890F46 /* EmptyElementEmptyStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyElementEmptyStringTests.swift; sourceTree = "<group>"; };
166167
4A062D4E2341924E009BCAC1 /* CombineTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombineTests.swift; sourceTree = "<group>"; };
168+
970FA9DB2422EFAE0023C1EC /* RootLevetExtraAttributesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootLevetExtraAttributesTests.swift; sourceTree = "<group>"; };
167169
B54555BB2343F5C1000D4128 /* EmptyArrayTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyArrayTest.swift; sourceTree = "<group>"; };
168170
B5E67532238B47E5006C8548 /* MixedChoiceAndNonChoiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MixedChoiceAndNonChoiceTests.swift; sourceTree = "<group>"; };
169171
B5E67534238B4960006C8548 /* IntOrString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntOrString.swift; sourceTree = "<group>"; };
@@ -452,30 +454,31 @@
452454
OBJ_90 /* DecodingContainerTests.swift */,
453455
OBJ_91 /* DynamicNodeDecodingTest.swift */,
454456
OBJ_92 /* DynamicNodeEncodingTest.swift */,
457+
B54555BB2343F5C1000D4128 /* EmptyArrayTest.swift */,
458+
07E441B92340F14B00890F46 /* EmptyElementEmptyStringTests.swift */,
455459
OBJ_93 /* ErrorContextTest.swift */,
460+
B5E67534238B4960006C8548 /* IntOrString.swift */,
456461
OBJ_94 /* KeyDecodingAndEncodingStrategyTests.swift */,
462+
B5E67532238B47E5006C8548 /* MixedChoiceAndNonChoiceTests.swift */,
457463
OBJ_113 /* MixedContainerTest.swift */,
458464
OBJ_114 /* NamespaceTest.swift */,
459465
OBJ_115 /* NestedAttributeChoiceTests.swift */,
466+
B5EA3BB4230F235C00D8D69B /* NestedChoiceArrayTest.swift */,
460467
OBJ_116 /* NestedChoiceTests.swift */,
461468
OBJ_117 /* NestingTests.swift */,
462469
OBJ_118 /* NodeEncodingStrategyTests.swift */,
463470
OBJ_119 /* NoteTest.swift */,
464471
OBJ_120 /* PlantCatalog.swift */,
465472
OBJ_121 /* PlantTest.swift */,
466-
07E441B92340F14B00890F46 /* EmptyElementEmptyStringTests.swift */,
467473
D18FBFB72348FAE500FA4F65 /* QuoteDecodingTest.swift */,
468474
OBJ_124 /* RelationshipsTest.swift */,
469475
OBJ_122 /* RJISample.swift */,
470476
OBJ_123 /* RJITest.swift */,
471477
B5F74471233F74E400BBDB15 /* RootLevelAttributeTest.swift */,
478+
970FA9DB2422EFAE0023C1EC /* RootLevetExtraAttributesTests.swift */,
472479
OBJ_125 /* SimpleChoiceTests.swift */,
473480
OBJ_126 /* SingleChildTests.swift */,
474481
OBJ_127 /* SpacePreserveTest.swift */,
475-
B5EA3BB4230F235C00D8D69B /* NestedChoiceArrayTest.swift */,
476-
B54555BB2343F5C1000D4128 /* EmptyArrayTest.swift */,
477-
B5E67532238B47E5006C8548 /* MixedChoiceAndNonChoiceTests.swift */,
478-
B5E67534238B4960006C8548 /* IntOrString.swift */,
479482
);
480483
name = XMLCoderTests;
481484
path = Tests/XMLCoderTests;
@@ -771,6 +774,7 @@
771774
OBJ_268 /* RJISample.swift in Sources */,
772775
B5E67535238B4960006C8548 /* IntOrString.swift in Sources */,
773776
OBJ_269 /* RJITest.swift in Sources */,
777+
970FA9DC2422EFAE0023C1EC /* RootLevetExtraAttributesTests.swift in Sources */,
774778
OBJ_270 /* RelationshipsTest.swift in Sources */,
775779
OBJ_271 /* SimpleChoiceTests.swift in Sources */,
776780
4A062D4F2341924E009BCAC1 /* CombineTests.swift in Sources */,

0 commit comments

Comments
 (0)