@@ -184,4 +184,167 @@ final class DynamicNodeDecodingTest: XCTestCase {
184
184
let test = try decoder. decode ( TestStruct . self, from: overlappingKeys)
185
185
XCTAssertEqual ( test, TestStruct ( attribute: 123 , element: " StringValue " ) )
186
186
}
187
+
188
+ struct Foo < T: Decodable > : Decodable {
189
+ var nested : T
190
+ }
191
+
192
+ struct ArrayFoo < T: Decodable > : Decodable {
193
+ var nested : [ T ]
194
+ }
195
+
196
+ struct NestedElement : Decodable , DynamicNodeDecoding {
197
+ var field1 : String
198
+ var field2 : String
199
+
200
+ static func nodeDecoding( for key: CodingKey ) -> XMLDecoder . NodeDecoding { . element }
201
+ }
202
+
203
+ struct NestedAttribute : Decodable , DynamicNodeDecoding {
204
+ var field1 : String
205
+ var field2 : String
206
+
207
+ static func nodeDecoding( for key: CodingKey ) -> XMLDecoder . NodeDecoding { . attribute }
208
+ }
209
+
210
+ struct NestedElementOrAttribute : Decodable , DynamicNodeDecoding {
211
+ var field1 : String
212
+ var field2 : String
213
+
214
+ static func nodeDecoding( for key: CodingKey ) -> XMLDecoder . NodeDecoding { . elementOrAttribute }
215
+ }
216
+
217
+ func testGenericKeyedFailsOnMissingValues( ) {
218
+ let failureElementXML =
219
+ """
220
+ <Root>
221
+ <nested><field1>value_1</field1></nested>
222
+ </Root>
223
+ """
224
+
225
+ let failureAttributeXML =
226
+ """
227
+ <Root>
228
+ <nested field1= " value_1 " />
229
+ </Root>
230
+ """
231
+
232
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedElement> . self , from: Data ( failureElementXML. utf8) ) ) {
233
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
234
+ }
235
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedAttribute> . self , from: Data ( failureElementXML. utf8) ) ) {
236
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
237
+ }
238
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedElementOrAttribute> . self , from: Data ( failureElementXML. utf8) ) ) {
239
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
240
+ }
241
+
242
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedElement> . self , from: Data ( failureAttributeXML. utf8) ) ) {
243
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
244
+ }
245
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedAttribute> . self , from: Data ( failureAttributeXML. utf8) ) ) {
246
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
247
+ }
248
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedElementOrAttribute> . self , from: Data ( failureAttributeXML. utf8) ) ) {
249
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
250
+ }
251
+ }
252
+
253
+ func testGenericUnkeyedFailsOnMissingValues( ) {
254
+ let failureAttributeXML =
255
+ """
256
+ <Root>
257
+ <nested field1= " value_1 " />
258
+ <nested field1= " value_1 " />
259
+ <nested field1= " value_1 " />
260
+ </Root>
261
+ """
262
+
263
+ let failureElementXML =
264
+ """
265
+ <Root>
266
+ <nested><field1>value_1</field1></nested>
267
+ <nested><field1>value_1</field1></nested>
268
+ <nested><field1>value_1</field1></nested>
269
+ </Root>
270
+ """
271
+
272
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElement> . self , from: Data ( failureAttributeXML. utf8) ) ) {
273
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
274
+ }
275
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedAttribute> . self , from: Data ( failureAttributeXML. utf8) ) ) {
276
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
277
+ }
278
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElementOrAttribute> . self , from: Data ( failureAttributeXML. utf8) ) ) {
279
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
280
+ }
281
+
282
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElement> . self , from: Data ( failureElementXML. utf8) ) ) {
283
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
284
+ }
285
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedAttribute> . self , from: Data ( failureElementXML. utf8) ) ) {
286
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
287
+ }
288
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElementOrAttribute> . self , from: Data ( failureElementXML. utf8) ) ) {
289
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
290
+ }
291
+ }
292
+
293
+ func testGenericKeyedSucceedsWithoutMissingValues( ) {
294
+ let successElementXML =
295
+ """
296
+ <Root>
297
+ <nested><field1>value_1</field1><field2>value_2</field2></nested>
298
+ </Root>
299
+ """
300
+
301
+ let successAttributeXML =
302
+ """
303
+ <Root>
304
+ <nested field1= " value_1 " field2= " value_2 " />
305
+ </Root>
306
+ """
307
+
308
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( Foo< NestedElement> . self , from: Data ( successElementXML. utf8) ) )
309
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedAttribute> . self , from: Data ( successElementXML. utf8) ) ) {
310
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
311
+ }
312
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( Foo< NestedElementOrAttribute> . self , from: Data ( successElementXML. utf8) ) )
313
+
314
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( Foo< NestedElement> . self , from: Data ( successAttributeXML. utf8) ) ) {
315
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
316
+ }
317
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( Foo< NestedAttribute> . self , from: Data ( successAttributeXML. utf8) ) )
318
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( Foo< NestedElementOrAttribute> . self , from: Data ( successAttributeXML. utf8) ) )
319
+ }
320
+
321
+ func testGenericUnkeyedSucceedsWithoutMissingValues( ) {
322
+ let successElementXML =
323
+ """
324
+ <Root>
325
+ <nested><field1>value_1</field1><field2>value_2</field2></nested>
326
+ <nested><field1>value_1</field1><field2>value_2</field2></nested>
327
+ </Root>
328
+ """
329
+
330
+ let successAttributeXML =
331
+ """
332
+ <Root>
333
+ <nested field1= " value_1 " field2= " value_2 " />
334
+ <nested field1= " value_1 " field2= " value_2 " />
335
+ </Root>
336
+ """
337
+
338
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElement> . self , from: Data ( successElementXML. utf8) ) )
339
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedAttribute> . self , from: Data ( successElementXML. utf8) ) ) {
340
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
341
+ }
342
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElementOrAttribute> . self , from: Data ( successElementXML. utf8) ) )
343
+
344
+ XCTAssertThrowsError ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElement> . self , from: Data ( successAttributeXML. utf8) ) ) {
345
+ guard case DecodingError . keyNotFound = $0 else { XCTFail ( " Invalid error thrown: \( $0) " ) ; return }
346
+ }
347
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedAttribute> . self , from: Data ( successAttributeXML. utf8) ) )
348
+ XCTAssertNoThrow ( try XMLDecoder ( ) . decode ( ArrayFoo< NestedElementOrAttribute> . self , from: Data ( successAttributeXML. utf8) ) )
349
+ }
187
350
}
0 commit comments