@@ -184,4 +184,167 @@ final class DynamicNodeDecodingTest: XCTestCase {
184184 let test = try decoder. decode ( TestStruct . self, from: overlappingKeys)
185185 XCTAssertEqual ( test, TestStruct ( attribute: 123 , element: " StringValue " ) )
186186 }
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+ }
187350}
0 commit comments