60d07df58d8572f5290c70ba5fc38cf9e6a3779c
[yangtools.git] / codec / yang-data-codec-xml / src / test / java / org / opendaylight / yangtools / yang / data / codec / xml / NormalizedNodesToXmlTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.codec.xml;
9
10 import java.io.IOException;
11 import java.util.Collection;
12 import java.util.Map;
13 import javax.xml.stream.XMLOutputFactory;
14 import javax.xml.stream.XMLStreamException;
15 import javax.xml.transform.dom.DOMResult;
16 import org.custommonkey.xmlunit.Diff;
17 import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener;
18 import org.custommonkey.xmlunit.XMLAssert;
19 import org.custommonkey.xmlunit.XMLUnit;
20 import org.junit.AfterClass;
21 import org.junit.Before;
22 import org.junit.BeforeClass;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.Parameterized;
26 import org.opendaylight.yangtools.util.xml.UntrustedXML;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.common.QNameModule;
29 import org.opendaylight.yangtools.yang.common.XMLNamespace;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
33 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
37 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
38 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
39 import org.xml.sax.SAXException;
40
41 @RunWith(Parameterized.class)
42 public class NormalizedNodesToXmlTest extends AbstractXmlTest {
43     @Parameterized.Parameters(name = "{0}")
44     public static Collection<Object[]> data() {
45         return TestFactories.junitParameters();
46     }
47
48     private QNameModule bazModule;
49
50     private QName outerContainer;
51
52     private QName myContainer1;
53     private QName myKeyedList;
54     private QName myKeyLeaf;
55     private QName myLeafInList1;
56     private QName myLeafInList2;
57     private QName myLeaf1;
58     private QName myLeafList;
59
60     private QName myContainer2;
61     private QName innerContainer;
62     private QName myLeaf2;
63     private QName myLeaf3;
64     private QName myChoice;
65     private QName myLeafInCase2;
66
67     private QName myContainer3;
68     private QName myDoublyKeyedList;
69     private QName myFirstKeyLeaf;
70     private QName mySecondKeyLeaf;
71     private QName myLeafInList3;
72
73     private static EffectiveModelContext SCHEMA_CONTEXT;
74
75     private final XMLOutputFactory factory;
76
77     public NormalizedNodesToXmlTest(final String factoryMode, final XMLOutputFactory factory) {
78         this.factory = factory;
79     }
80
81     @BeforeClass
82     public static void beforeClass() {
83         SCHEMA_CONTEXT = YangParserTestUtils.parseYangResource("/baz.yang");
84     }
85
86     @AfterClass
87     public static void afterClass() {
88         SCHEMA_CONTEXT = null;
89     }
90
91     @Before
92     public void setup() {
93         bazModule = QNameModule.create(XMLNamespace.of("baz-namespace"));
94
95         outerContainer = QName.create(bazModule, "outer-container");
96
97         myContainer1 = QName.create(bazModule, "my-container-1");
98         myKeyedList = QName.create(bazModule, "my-keyed-list");
99         myKeyLeaf = QName.create(bazModule, "my-key-leaf");
100         myLeafInList1 = QName.create(bazModule, "my-leaf-in-list-1");
101         myLeafInList2 = QName.create(bazModule, "my-leaf-in-list-2");
102         myLeaf1 = QName.create(bazModule, "my-leaf-1");
103         myLeafList = QName.create(bazModule, "my-leaf-list");
104
105         myContainer2 = QName.create(bazModule, "my-container-2");
106         innerContainer = QName.create(bazModule, "inner-container");
107         myLeaf2 = QName.create(bazModule, "my-leaf-2");
108         myLeaf3 = QName.create(bazModule, "my-leaf-3");
109         myChoice = QName.create(bazModule, "my-choice");
110         myLeafInCase2 = QName.create(bazModule, "my-leaf-in-case-2");
111
112         myContainer3 = QName.create(bazModule, "my-container-3");
113         myDoublyKeyedList = QName.create(bazModule, "my-doubly-keyed-list");
114         myFirstKeyLeaf = QName.create(bazModule, "my-first-key-leaf");
115         mySecondKeyLeaf = QName.create(bazModule, "my-second-key-leaf");
116         myLeafInList3 = QName.create(bazModule, "my-leaf-in-list-3");
117     }
118
119     @Test
120     public void testNormalizedNodeToXmlSerialization() throws XMLStreamException, IOException, SAXException {
121         final var doc = loadDocument("/baz.xml");
122         final var domResult = new DOMResult(UntrustedXML.newDocumentBuilder().newDocument());
123         final var xmlStreamWriter = factory.createXMLStreamWriter(domResult);
124         final var xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlStreamWriter,
125             SCHEMA_CONTEXT);
126         final var normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(xmlNormalizedNodeStreamWriter);
127
128         normalizedNodeWriter.write(buildOuterContainerNode());
129
130         XMLUnit.setIgnoreWhitespace(true);
131         XMLUnit.setNormalize(true);
132
133         final String expectedXml = toString(doc.getDocumentElement());
134         final String serializedXml = toString(domResult.getNode());
135         final Diff diff = new Diff(expectedXml, serializedXml);
136         diff.overrideDifferenceListener(new IgnoreTextAndAttributeValuesDifferenceListener());
137
138         XMLAssert.assertXMLEqual(diff, true);
139     }
140
141     private ContainerNode buildOuterContainerNode() {
142         return Builders.containerBuilder()
143             .withNodeIdentifier(new NodeIdentifier(outerContainer))
144             .withChild(Builders.containerBuilder()
145                 .withNodeIdentifier(new NodeIdentifier(myContainer1))
146                 .withChild(Builders.mapBuilder()
147                     .withNodeIdentifier(new NodeIdentifier(myKeyedList))
148                     .withChild(Builders.mapEntryBuilder()
149                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue1"))
150                         .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue1"))
151                         .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue2"))
152                         .build())
153                     .withChild(Builders.mapEntryBuilder()
154                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue2"))
155                         .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue12"))
156                         .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue22"))
157                         .build())
158                     .build())
159                 .withChild(ImmutableNodes.leafNode(myLeaf1, "value1"))
160                 .withChild(Builders.leafSetBuilder()
161                     .withNodeIdentifier(new NodeIdentifier(myLeafList))
162                     .withChild(Builders.leafSetEntryBuilder()
163                         .withNodeIdentifier(new NodeWithValue<>(myLeafList, "lflvalue1"))
164                         .withValue("lflvalue1")
165                         .build())
166                     .withChild(Builders.leafSetEntryBuilder()
167                         .withNodeIdentifier(new NodeWithValue<>(myLeafList, "lflvalue2"))
168                         .withValue("lflvalue2")
169                         .build())
170                     .build())
171                 .build())
172             .withChild(Builders.containerBuilder()
173                 .withNodeIdentifier(new NodeIdentifier(myContainer2))
174                 .withChild(Builders.containerBuilder()
175                     .withNodeIdentifier(new NodeIdentifier(innerContainer))
176                     .withChild(ImmutableNodes.leafNode(myLeaf2, "value2"))
177                     .build())
178                 .withChild(ImmutableNodes.leafNode(myLeaf3, "value3"))
179                 .withChild(Builders.choiceBuilder()
180                     .withNodeIdentifier(new NodeIdentifier(myChoice))
181                     .withChild(ImmutableNodes.leafNode(myLeafInCase2, "case2value"))
182                     .build())
183                 .build())
184             .withChild(Builders.containerBuilder()
185                 .withNodeIdentifier(new NodeIdentifier(myContainer3))
186                 .withChild(Builders.mapBuilder()
187                     .withNodeIdentifier(new NodeIdentifier(myDoublyKeyedList))
188                     .withChild(Builders.mapEntryBuilder()
189                         .withNodeIdentifier(NodeIdentifierWithPredicates.of(myDoublyKeyedList,
190                             Map.of(myFirstKeyLeaf, "listkeyvalue1", mySecondKeyLeaf, "listkeyvalue2")))
191                         .withChild(ImmutableNodes.leafNode(myLeafInList3, "listleafvalue1"))
192                         .build())
193                     .build())
194                 .build())
195             .build();
196     }
197 }