-
Notifications
You must be signed in to change notification settings - Fork 104
/
MixedChoiceAndNonChoiceTests.swift
198 lines (169 loc) · 7.33 KB
/
MixedChoiceAndNonChoiceTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//
// MixedChoiceAndNonChoiceTests.swift
// XMLCoderTests
//
// Created by Benjamin Wetherfield on 11/24/19.
//
import XCTest
import XMLCoder
private enum AlternateIntOrString: Equatable {
case alternateInt(Int)
case alternateString(String)
}
extension AlternateIntOrString: Codable {
enum CodingKeys: String, CodingKey {
case alternateInt = "alternate-int"
case alternateString = "alternate-string"
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .alternateInt(int):
try container.encode(int, forKey: .alternateInt)
case let .alternateString(string):
try container.encode(string, forKey: .alternateString)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if container.contains(.alternateInt) {
self = .alternateInt(try container.decode(Int.self, forKey: .alternateInt))
} else {
self = .alternateString(try container.decode(String.self, forKey: .alternateString))
}
}
}
extension AlternateIntOrString.CodingKeys: XMLChoiceCodingKey {}
private struct MixedIntOrStringFirst: Equatable {
let intOrString: IntOrString
let otherValue: String
}
extension MixedIntOrStringFirst: Codable {
enum CodingKeys: String, CodingKey {
case otherValue = "other-value"
}
func encode(to encoder: Encoder) throws {
try intOrString.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(otherValue, forKey: .otherValue)
}
init(from decoder: Decoder) throws {
intOrString = try IntOrString(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
otherValue = try container.decode(String.self, forKey: .otherValue)
}
}
private struct MixedOtherFirst: Equatable {
let intOrString: IntOrString
let otherValue: String
}
extension MixedOtherFirst: Codable {
enum CodingKeys: String, CodingKey {
case otherValue = "other-value"
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(otherValue, forKey: .otherValue)
try intOrString.encode(to: encoder)
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
otherValue = try container.decode(String.self, forKey: .otherValue)
intOrString = try IntOrString(from: decoder)
}
}
private struct MixedEitherSide: Equatable {
let leading: String
let intOrString: IntOrString
let trailing: String
}
extension MixedEitherSide: Codable {
enum CodingKeys: String, CodingKey {
case leading
case trailing
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(leading, forKey: .leading)
try intOrString.encode(to: encoder)
try container.encode(trailing, forKey: .trailing)
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
leading = try container.decode(String.self, forKey: .leading)
intOrString = try IntOrString(from: decoder)
trailing = try container.decode(String.self, forKey: .trailing)
}
}
private struct TwoChoiceElements: Equatable {
let first: IntOrString
let second: AlternateIntOrString
}
extension TwoChoiceElements: Codable {
func encode(to encoder: Encoder) throws {
try first.encode(to: encoder)
try second.encode(to: encoder)
}
init(from decoder: Decoder) throws {
first = try IntOrString(from: decoder)
second = try AlternateIntOrString(from: decoder)
}
}
final class MixedChoiceAndNonChoiceTests: XCTestCase {
func testMixedChoiceFirstEncode() throws {
let first = MixedIntOrStringFirst(intOrString: .int(4), otherValue: "other")
let firstEncoded = try XMLEncoder().encode(first, withRootKey: "container")
let firstExpectedXML = "<container><int>4</int><other-value>other</other-value></container>"
XCTAssertEqual(String(data: firstEncoded, encoding: .utf8), firstExpectedXML)
}
func testMixedChoiceFirstDecode() throws {
let xmlString = "<container><int>4</int><other-value>other</other-value></container>"
let xmlData = xmlString.data(using: .utf8)!
let decoded = try XMLDecoder().decode(MixedIntOrStringFirst.self, from: xmlData)
let expected = MixedIntOrStringFirst(intOrString: .int(4), otherValue: "other")
XCTAssertEqual(decoded, expected)
}
func testMixedChoiceSecondEncode() throws {
let second = MixedOtherFirst(intOrString: .int(4), otherValue: "other")
let secondEncoded = try XMLEncoder().encode(second, withRootKey: "container")
let secondExpectedXML = "<container><other-value>other</other-value><int>4</int></container>"
XCTAssertEqual(String(data: secondEncoded, encoding: .utf8), secondExpectedXML)
}
func testMixedChoiceSecondDecode() throws {
let xmlString = "<container><other-value>other</other-value><int>4</int></container>"
let xmlData = xmlString.data(using: .utf8)!
let decoded = try XMLDecoder().decode(MixedOtherFirst.self, from: xmlData)
let expected = MixedOtherFirst(intOrString: .int(4), otherValue: "other")
XCTAssertEqual(decoded, expected)
}
func testMixedChoiceFlankedEncode() throws {
let flanked = MixedEitherSide(leading: "first", intOrString: .string("then"), trailing: "second")
let flankedEncoded = try XMLEncoder().encode(flanked, withRootKey: "container")
let flankedExpectedXML = """
<container><leading>first</leading><string>then</string><trailing>second</trailing></container>
"""
XCTAssertEqual(String(data: flankedEncoded, encoding: .utf8), flankedExpectedXML)
}
func testMixedChoiceFlankedDecode() throws {
let xmlString = """
<container><leading>first</leading><string>then</string><trailing>second</trailing></container>
"""
let xmlData = xmlString.data(using: .utf8)!
let decoded = try XMLDecoder().decode(MixedEitherSide.self, from: xmlData)
let expected = MixedEitherSide(leading: "first", intOrString: .string("then"), trailing: "second")
XCTAssertEqual(decoded, expected)
}
func testTwoChoiceElementsEncode() throws {
let twoChoiceElements = TwoChoiceElements(first: .int(1), second: .alternateString("one"))
let encoded = try XMLEncoder().encode(twoChoiceElements, withRootKey: "container")
let expectedXML = "<container><int>1</int><alternate-string>one</alternate-string></container>"
XCTAssertEqual(String(data: encoded, encoding: .utf8), expectedXML)
}
func testTwoChoiceElementsDecode() throws {
let xmlString = "<container><int>1</int><alternate-string>one</alternate-string></container>"
let xmlData = xmlString.data(using: .utf8)!
let decoded = try XMLDecoder().decode(TwoChoiceElements.self, from: xmlData)
let expected = TwoChoiceElements(first: .int(1), second: .alternateString("one"))
XCTAssertEqual(decoded, expected)
}
}