|
| 1 | +package tools.jackson.dataformat.xml.tofix; |
| 2 | + |
| 3 | +import org.junit.jupiter.api.Test; |
| 4 | + |
| 5 | +import tools.jackson.databind.ObjectMapper; |
| 6 | +import tools.jackson.dataformat.xml.XmlTestUtil; |
| 7 | +import tools.jackson.dataformat.xml.annotation.JacksonXmlProperty; |
| 8 | +import tools.jackson.dataformat.xml.annotation.JacksonXmlText; |
| 9 | +import tools.jackson.dataformat.xml.testutil.failure.JacksonTestFailureExpected; |
| 10 | + |
| 11 | +import static org.junit.jupiter.api.Assertions.assertEquals; |
| 12 | +import static org.junit.jupiter.api.Assertions.assertNotNull; |
| 13 | +import static org.junit.jupiter.api.Assertions.assertNull; |
| 14 | + |
| 15 | +// [dataformat-xml#608] Fails to instantiate class when only text node is present |
| 16 | +// and the target type has @JacksonXmlText plus other element properties. |
| 17 | +public class XmlTextOnlyDeser608Test extends XmlTestUtil |
| 18 | +{ |
| 19 | + static class Root608 { |
| 20 | + public Nested608 nested; |
| 21 | + public Plain608 plain; |
| 22 | + } |
| 23 | + |
| 24 | + // Has @JacksonXmlText AND other element properties |
| 25 | + static class Nested608 { |
| 26 | + @JacksonXmlProperty(isAttribute = false) |
| 27 | + public String other; |
| 28 | + |
| 29 | + @JacksonXmlProperty(isAttribute = false) |
| 30 | + public String reallyNotHere; |
| 31 | + |
| 32 | + @JacksonXmlText |
| 33 | + public String text; |
| 34 | + } |
| 35 | + |
| 36 | + // Has only @JacksonXmlText, no other properties |
| 37 | + static class Plain608 { |
| 38 | + @JacksonXmlText |
| 39 | + public String text; |
| 40 | + } |
| 41 | + |
| 42 | + private final ObjectMapper MAPPER = newMapper(); |
| 43 | + |
| 44 | + // Works: nested has both a child element and text content |
| 45 | + @Test |
| 46 | + public void testNestedWithChildAndText608() throws Exception { |
| 47 | + String xml = "<Root608>" |
| 48 | + + "<nested><other>text</other>The text node.</nested>" |
| 49 | + + "</Root608>"; |
| 50 | + Root608 result = MAPPER.readValue(xml, Root608.class); |
| 51 | + assertNotNull(result.nested); |
| 52 | + assertEquals("text", result.nested.other); |
| 53 | + assertEquals("The text node.", result.nested.text); |
| 54 | + } |
| 55 | + |
| 56 | + // Works: plain type only has @JacksonXmlText |
| 57 | + @Test |
| 58 | + public void testPlainTextOnly608() throws Exception { |
| 59 | + String xml = "<Root608><plain>The text node.</plain></Root608>"; |
| 60 | + Root608 result = MAPPER.readValue(xml, Root608.class); |
| 61 | + assertNotNull(result.plain); |
| 62 | + assertEquals("The text node.", result.plain.text); |
| 63 | + } |
| 64 | + |
| 65 | + // Fails: nested type has @JacksonXmlText plus other element properties, |
| 66 | + // but XML only contains text (no child elements). Jackson incorrectly |
| 67 | + // tries String-argument constructor instead of object deserialization. |
| 68 | + @JacksonTestFailureExpected |
| 69 | + @Test |
| 70 | + public void testNestedWithOnlyText608() throws Exception { |
| 71 | + String xml = "<Root608><nested>The text node.</nested></Root608>"; |
| 72 | + Root608 result = MAPPER.readValue(xml, Root608.class); |
| 73 | + assertNotNull(result.nested); |
| 74 | + assertNull(result.nested.other); |
| 75 | + assertNull(result.nested.reallyNotHere); |
| 76 | + assertEquals("The text node.", result.nested.text); |
| 77 | + } |
| 78 | +} |
0 commit comments