6fde4e592a9799ffd92ec3b24d74995b705548e3
[yangtools.git] / parser / yang-parser-rfc7950 / src / test / java / org / opendaylight / yangtools / yang / stmt / GroupingTest.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.stmt;
9
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertNull;
16 import static org.junit.Assert.assertTrue;
17
18 import com.google.common.collect.Iterables;
19 import java.util.Collection;
20 import java.util.Map;
21 import java.util.Optional;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.common.Revision;
28 import org.opendaylight.yangtools.yang.common.XMLNamespace;
29 import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
35 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
38 import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
39 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
40 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.Module;
43 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
44 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
46 import org.opendaylight.yangtools.yang.model.api.UsesNode;
47 import org.opendaylight.yangtools.yang.model.api.stmt.RefineEffectiveStatement;
48 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant;
49 import org.opendaylight.yangtools.yang.model.api.stmt.UnrecognizedStatement;
50
51 public class GroupingTest {
52     private static EffectiveModelContext CTX;
53     private static Module FOO;
54     private static Module BAZ;
55
56     @BeforeClass
57     public static void beforeClass() throws Exception {
58         CTX = TestUtils.parseYangSources("/model");
59         assertEquals(3, CTX.getModules().size());
60
61         FOO = Iterables.getOnlyElement(CTX.findModules("foo"));
62         BAZ = Iterables.getOnlyElement(CTX.findModules("baz"));
63     }
64
65     @Test
66     public void testRefine() {
67         final ContainerSchemaNode peer = (ContainerSchemaNode) FOO.getDataChildByName(QName.create(
68                 FOO.getQNameModule(), "peer"));
69         final ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName(QName.create(
70                 FOO.getQNameModule(), "destination"));
71
72         final Collection<? extends UsesNode> usesNodes = destination.getUses();
73         assertEquals(1, usesNodes.size());
74         final UsesNode usesNode = usesNodes.iterator().next();
75         final Map<Descendant, SchemaNode> refines = usesNode.getRefines();
76         assertEquals(4, refines.size());
77
78         LeafSchemaNode refineLeaf = null;
79         ContainerSchemaNode refineContainer = null;
80         ListSchemaNode refineList = null;
81         LeafSchemaNode refineInnerLeaf = null;
82         for (final Map.Entry<Descendant, SchemaNode> entry : refines.entrySet()) {
83             final SchemaNode value = entry.getValue();
84             if ("address".equals(value.getQName().getLocalName())) {
85                 refineLeaf = (LeafSchemaNode) destination.getDataChildByName(value.getQName());
86             } else if ("port".equals(value.getQName().getLocalName())) {
87                 refineContainer = (ContainerSchemaNode) destination.getDataChildByName(value.getQName());
88             } else if ("addresses".equals(value.getQName().getLocalName())) {
89                 refineList = (ListSchemaNode) destination.getDataChildByName(value.getQName());
90             }
91         }
92
93         assertNotNull(refineList);
94         for (final Map.Entry<Descendant, SchemaNode> entry : refines.entrySet()) {
95             final SchemaNode value = entry.getValue();
96             if ("id".equals(value.getQName().getLocalName())) {
97                 refineInnerLeaf = (LeafSchemaNode) refineList.getDataChildByName(value.getQName());
98             }
99         }
100
101         // leaf address
102         assertNotNull(refineLeaf);
103         assertEquals(Optional.of("IP address of target node"), refineLeaf.getDescription());
104         assertEquals(Optional.of("address reference added by refine"), refineLeaf.getReference());
105         assertEquals(Optional.of(Boolean.FALSE), refineLeaf.effectiveConfig());
106         assertFalse(refineLeaf.isMandatory());
107         final Collection<? extends MustDefinition> leafMustConstraints = refineLeaf.getMustConstraints();
108         assertEquals(1, leafMustConstraints.size());
109         final MustDefinition leafMust = leafMustConstraints.iterator().next();
110         assertEquals("ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)", leafMust.getXpath().toString());
111         assertEquals(0, refineLeaf.getUnknownSchemaNodes().size());
112         assertEquals(1, usesNode.asEffectiveStatement()
113             .findFirstEffectiveSubstatement(RefineEffectiveStatement.class).orElseThrow().getDeclared()
114             .declaredSubstatements(UnrecognizedStatement.class).size());
115
116         // container port
117         assertNotNull(refineContainer);
118         final Collection<? extends MustDefinition> mustConstraints = refineContainer.getMustConstraints();
119         assertTrue(mustConstraints.isEmpty());
120         assertEquals(Optional.of("description of port defined by refine"), refineContainer.getDescription());
121         assertEquals(Optional.of("port reference added by refine"), refineContainer.getReference());
122         assertEquals(Optional.of(Boolean.FALSE), refineContainer.effectiveConfig());
123         assertTrue(refineContainer.isPresenceContainer());
124
125         // list addresses
126         assertEquals(Optional.of("description of addresses defined by refine"), refineList.getDescription());
127         assertEquals(Optional.of("addresses reference added by refine"), refineList.getReference());
128         assertEquals(Optional.of(Boolean.FALSE), refineList.effectiveConfig());
129
130         final ElementCountConstraint constraint = refineList.getElementCountConstraint().get();
131         assertEquals((Object) 2, constraint.getMinElements());
132         assertNull(constraint.getMaxElements());
133
134         // leaf id
135         assertNotNull(refineInnerLeaf);
136         assertEquals(Optional.of("id of address"), refineInnerLeaf.getDescription());
137     }
138
139     @Test
140     public void testGrouping() {
141         final Collection<? extends GroupingDefinition> groupings = BAZ.getGroupings();
142         assertEquals(1, groupings.size());
143         final GroupingDefinition grouping = groupings.iterator().next();
144         final Collection<? extends DataSchemaNode> children = grouping.getChildNodes();
145         assertEquals(5, children.size());
146     }
147
148     @Test
149     public void testUses() {
150         // suffix _u = added by uses
151         // suffix _g = defined in grouping
152
153
154         // get grouping
155         final Collection<? extends GroupingDefinition> groupings = BAZ.getGroupings();
156         assertEquals(1, groupings.size());
157         final GroupingDefinition grouping = groupings.iterator().next();
158
159         // get node containing uses
160         final ContainerSchemaNode peer = (ContainerSchemaNode) FOO.getDataChildByName(QName.create(
161                 FOO.getQNameModule(), "peer"));
162         final ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName(QName.create(
163                 FOO.getQNameModule(), "destination"));
164
165         // check uses
166         final Collection<? extends UsesNode> uses = destination.getUses();
167         assertEquals(1, uses.size());
168
169         // check uses process
170         final AnyxmlSchemaNode data_u = (AnyxmlSchemaNode) destination.getDataChildByName(QName.create(
171                 FOO.getQNameModule(), "data"));
172         assertNotNull(data_u);
173         assertTrue(data_u.isAddedByUses());
174
175         final AnyxmlSchemaNode data_g = (AnyxmlSchemaNode) grouping.getDataChildByName(QName.create(
176                 BAZ.getQNameModule(), "data"));
177         assertNotNull(data_g);
178         assertFalse(data_g.isAddedByUses());
179         assertFalse(data_u.equals(data_g));
180         assertEquals(data_g, extractOriginal(data_u));
181
182         final ChoiceSchemaNode how_u = (ChoiceSchemaNode) destination.getDataChildByName(QName.create(
183                 FOO.getQNameModule(), "how"));
184         assertNotNull(how_u);
185         assertIsAddedByUses(how_u, true);
186         assertEquals(2, how_u.getCases().size());
187
188         final ChoiceSchemaNode how_g = (ChoiceSchemaNode) grouping.getDataChildByName(QName.create(
189                 BAZ.getQNameModule(), "how"));
190         assertNotNull(how_g);
191         assertIsAddedByUses(how_g, false);
192         assertEquals(2, how_g.getCases().size());
193         assertFalse(how_u.equals(how_g));
194         assertEquals(how_g, extractOriginal(how_u));
195
196         final LeafSchemaNode address_u = (LeafSchemaNode) destination.getDataChildByName(QName.create(
197                 FOO.getQNameModule(), "address"));
198         assertNotNull(address_u);
199         assertEquals(Optional.of("1.2.3.4"), address_u.getType().getDefaultValue());
200         assertEquals(Optional.of("IP address of target node"), address_u.getDescription());
201         assertEquals(Optional.of("address reference added by refine"), address_u.getReference());
202         assertEquals(Optional.of(Boolean.FALSE), address_u.effectiveConfig());
203         assertTrue(address_u.isAddedByUses());
204         assertFalse(address_u.isMandatory());
205
206         final LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName(QName.create(
207                 BAZ.getQNameModule(), "address"));
208         assertNotNull(address_g);
209         assertFalse(address_g.isAddedByUses());
210         assertEquals(Optional.empty(), address_g.getType().getDefaultValue());
211         assertEquals(Optional.of("Target IP address"), address_g.getDescription());
212         assertFalse(address_g.getReference().isPresent());
213         assertEquals(Optional.empty(), address_g.effectiveConfig());
214         assertFalse(address_u.equals(address_g));
215         assertTrue(address_g.isMandatory());
216         assertEquals(address_g, extractOriginal(address_u));
217
218         final ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName(QName.create(
219                 FOO.getQNameModule(), "port"));
220         assertNotNull(port_u);
221         assertIsAddedByUses(port_u, true);
222
223         final ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName(QName.create(
224                 BAZ.getQNameModule(), "port"));
225         assertNotNull(port_g);
226         assertIsAddedByUses(port_g, false);
227         assertFalse(port_u.equals(port_g));
228         assertEquals(port_g, extractOriginal(port_u));
229
230         final ListSchemaNode addresses_u = (ListSchemaNode) destination.getDataChildByName(QName.create(
231                 FOO.getQNameModule(), "addresses"));
232         assertNotNull(addresses_u);
233         assertIsAddedByUses(addresses_u, true);
234
235         final ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName(QName.create(
236                 BAZ.getQNameModule(), "addresses"));
237         assertNotNull(addresses_g);
238         assertIsAddedByUses(addresses_g, false);
239         assertFalse(addresses_u.equals(addresses_g));
240         assertEquals(addresses_g, extractOriginal(addresses_u));
241
242         // grouping defined by 'uses'
243         final Collection<? extends GroupingDefinition> groupings_u = destination.getGroupings();
244         assertEquals(0, groupings_u.size());
245
246         // grouping defined in 'grouping' node
247         final Collection<? extends GroupingDefinition> groupings_g = grouping.getGroupings();
248         assertEquals(1, groupings_g.size());
249         final GroupingDefinition grouping_g = groupings_g.iterator().next();
250         assertIsAddedByUses(grouping_g, false);
251
252         assertEquals(0, destination.getUnknownSchemaNodes().size());
253         assertEquals(1,
254             grouping.asEffectiveStatement().getDeclared().declaredSubstatements(UnrecognizedStatement.class).size());
255     }
256
257     @Test
258     public void testUsesUnderModule() {
259         // suffix _u = added by uses
260         // suffix _g = defined in grouping
261
262         // get grouping
263         final Collection<? extends GroupingDefinition> groupings = BAZ.getGroupings();
264         assertEquals(1, groupings.size());
265         final GroupingDefinition grouping = groupings.iterator().next();
266
267         // check uses
268         final Collection<? extends UsesNode> uses = FOO.getUses();
269         assertEquals(1, uses.size());
270
271         // check uses process
272         final AnyxmlSchemaNode data_u = (AnyxmlSchemaNode) FOO.getDataChildByName(QName.create(FOO.getQNameModule(),
273                 "data"));
274         assertNotNull(data_u);
275         assertTrue(data_u.isAddedByUses());
276
277         final AnyxmlSchemaNode data_g = (AnyxmlSchemaNode) grouping.getDataChildByName(QName.create(
278             BAZ.getQNameModule(), "data"));
279         assertNotNull(data_g);
280         assertFalse(data_g.isAddedByUses());
281         assertFalse(data_u.equals(data_g));
282         assertEquals(data_g, extractOriginal(data_u));
283
284         final ChoiceSchemaNode how_u = (ChoiceSchemaNode) FOO.getDataChildByName(QName.create(FOO.getQNameModule(),
285                 "how"));
286         assertNotNull(how_u);
287         assertIsAddedByUses(how_u, true);
288         assertFalse(how_u.isAugmenting());
289         final Collection<? extends CaseSchemaNode> cases_u = how_u.getCases();
290         assertEquals(2, cases_u.size());
291         final CaseSchemaNode interval = how_u.findCaseNodes("interval").iterator().next();
292         assertFalse(interval.isAugmenting());
293         final LeafSchemaNode name = (LeafSchemaNode) interval.getDataChildByName(QName.create(FOO.getQNameModule(),
294                 "name"));
295         assertTrue(name.isAugmenting());
296         final LeafSchemaNode intervalLeaf = (LeafSchemaNode) interval.getDataChildByName(QName.create(
297                 FOO.getQNameModule(), "interval"));
298         assertFalse(intervalLeaf.isAugmenting());
299
300         final ChoiceSchemaNode how_g = (ChoiceSchemaNode) grouping.getDataChildByName(QName.create(
301                 BAZ.getQNameModule(), "how"));
302         assertNotNull(how_g);
303         assertIsAddedByUses(how_g, false);
304         assertFalse(how_u.equals(how_g));
305         assertEquals(how_g, extractOriginal(how_u));
306
307         final LeafSchemaNode address_u = (LeafSchemaNode) FOO.getDataChildByName(QName.create(FOO.getQNameModule(),
308                 "address"));
309         assertNotNull(address_u);
310         assertEquals(Optional.empty(), address_u.getType().getDefaultValue());
311         assertEquals(Optional.of("Target IP address"), address_u.getDescription());
312         assertFalse(address_u.getReference().isPresent());
313         assertEquals(Optional.empty(), address_u.effectiveConfig());
314         assertTrue(address_u.isAddedByUses());
315
316         final LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName(QName.create(
317                 BAZ.getQNameModule(), "address"));
318         assertNotNull(address_g);
319         assertFalse(address_g.isAddedByUses());
320         assertEquals(Optional.empty(), address_g.getType().getDefaultValue());
321         assertEquals(Optional.of("Target IP address"), address_g.getDescription());
322         assertFalse(address_g.getReference().isPresent());
323         assertEquals(Optional.empty(), address_g.effectiveConfig());
324         assertFalse(address_u.equals(address_g));
325         assertEquals(address_g, extractOriginal(address_u));
326
327         final ContainerSchemaNode port_u = (ContainerSchemaNode) FOO.getDataChildByName(QName.create(
328                 FOO.getQNameModule(), "port"));
329         assertNotNull(port_u);
330         assertIsAddedByUses(port_u, true);
331
332         final ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName(QName.create(
333                 BAZ.getQNameModule(), "port"));
334         assertNotNull(port_g);
335         assertIsAddedByUses(port_g, false);
336         assertFalse(port_u.equals(port_g));
337         assertEquals(port_g, extractOriginal(port_u));
338
339         final ListSchemaNode addresses_u = (ListSchemaNode) FOO.getDataChildByName(QName.create(FOO.getQNameModule(),
340                 "addresses"));
341         assertNotNull(addresses_u);
342         assertIsAddedByUses(addresses_u, true);
343
344         final ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName(QName.create(
345                 BAZ.getQNameModule(), "addresses"));
346         assertNotNull(addresses_g);
347         assertIsAddedByUses(addresses_g, false);
348         assertFalse(addresses_u.equals(addresses_g));
349         assertEquals(addresses_g, extractOriginal(addresses_u));
350
351         // grouping defined by 'uses'
352         final Collection<? extends GroupingDefinition> groupings_u = FOO.getGroupings();
353         assertEquals(0, groupings_u.size());
354
355         // grouping defined in 'grouping' node
356         final Collection<? extends GroupingDefinition> groupings_g = grouping.getGroupings();
357         assertEquals(1, groupings_g.size());
358         final GroupingDefinition grouping_g = groupings_g.iterator().next();
359         assertIsAddedByUses(grouping_g, false);
360
361         assertEquals(0, grouping.getUnknownSchemaNodes().size());
362         assertEquals(1, grouping.asEffectiveStatement().getDeclared().declaredSubstatements(UnrecognizedStatement.class)
363             .size());
364
365         final UsesNode un = uses.iterator().next();
366         final Collection<? extends AugmentationSchemaNode> usesAugments = un.getAugmentations();
367         assertEquals(1, usesAugments.size());
368         final AugmentationSchemaNode augment = usesAugments.iterator().next();
369         assertEquals(Optional.of("inner augment"), augment.getDescription());
370         final Collection<? extends DataSchemaNode> children = augment.getChildNodes();
371         assertEquals(1, children.size());
372         final DataSchemaNode leaf = children.iterator().next();
373         assertTrue(leaf instanceof LeafSchemaNode);
374         assertEquals("name", leaf.getQName().getLocalName());
375     }
376
377     @Test
378     public void testCascadeUses() throws Exception {
379         final EffectiveModelContext loadModules = TestUtils.parseYangSource("/grouping-test/cascade-uses.yang");
380         assertEquals(1, loadModules.getModules().size());
381
382         final Module testModule =  Iterables.getOnlyElement(loadModules.findModules("cascade-uses"));
383         final QNameModule namespace = testModule.getQNameModule();
384         final Collection<? extends GroupingDefinition> groupings = testModule.getGroupings();
385
386         GroupingDefinition gu = null;
387         GroupingDefinition gv = null;
388         GroupingDefinition gx = null;
389         GroupingDefinition gy = null;
390         GroupingDefinition gz = null;
391         GroupingDefinition gzz = null;
392         for (final GroupingDefinition gd : groupings) {
393             final String name = gd.getQName().getLocalName();
394             switch (name) {
395                 case "grouping-U":
396                     gu = gd;
397                     break;
398                 case "grouping-V":
399                     gv = gd;
400                     break;
401                 case "grouping-X":
402                     gx = gd;
403                     break;
404                 case "grouping-Y":
405                     gy = gd;
406                     break;
407                 case "grouping-Z":
408                     gz = gd;
409                     break;
410                 case "grouping-ZZ":
411                     gzz = gd;
412                     break;
413                 default:
414                     break;
415             }
416         }
417         assertNotNull(gu);
418         assertNotNull(gv);
419         assertNotNull(gx);
420         assertNotNull(gy);
421         assertNotNull(gz);
422         assertNotNull(gzz);
423
424         final QNameModule expectedModule = QNameModule.create(XMLNamespace.of("urn:grouping:cascade-uses"),
425             Revision.of("2013-07-18"));
426
427         // grouping-U
428         Collection<? extends DataSchemaNode> childNodes = gu.getChildNodes();
429         assertEquals(7, childNodes.size());
430
431         final LeafSchemaNode leafGroupingU = (LeafSchemaNode) gu.getDataChildByName(
432             QName.create(namespace, "leaf-grouping-U"));
433         assertNotNull(leafGroupingU);
434         assertFalse(leafGroupingU.isAddedByUses());
435         assertNull(extractOriginal(leafGroupingU));
436
437         for (final DataSchemaNode childNode : childNodes) {
438             if (!childNode.getQName().equals(leafGroupingU.getQName())) {
439                 assertIsAddedByUses(childNode, true);
440             }
441         }
442
443         // grouping-V
444         childNodes = gv.getChildNodes();
445         assertEquals(4, childNodes.size());
446         LeafSchemaNode leafGroupingV = null;
447         ContainerSchemaNode containerGroupingV = null;
448         for (final DataSchemaNode childNode : childNodes) {
449             if ("leaf-grouping-V".equals(childNode.getQName().getLocalName())) {
450                 leafGroupingV = (LeafSchemaNode) childNode;
451             } else if ("container-grouping-V".equals(childNode.getQName().getLocalName())) {
452                 containerGroupingV = (ContainerSchemaNode) childNode;
453             } else {
454                 assertIsAddedByUses(childNode, true);
455             }
456         }
457         assertNotNull(leafGroupingV);
458         assertFalse(leafGroupingV.isAddedByUses());
459
460         // grouping-V/container-grouping-V
461         assertNotNull(containerGroupingV);
462         assertFalse(containerGroupingV.isAddedByUses());
463         assertEquals(QName.create(expectedModule, "container-grouping-V"), containerGroupingV.getQName());
464         childNodes = containerGroupingV.getChildNodes();
465         assertEquals(2, childNodes.size());
466         for (final DataSchemaNode childNode : childNodes) {
467             assertIsAddedByUses(childNode, true);
468         }
469
470         // grouping-V/container-grouping-V/leaf-grouping-X
471         final LeafSchemaNode leafXinContainerV = (LeafSchemaNode) containerGroupingV.getDataChildByName(
472             QName.create(namespace, "leaf-grouping-X"));
473         assertEquals(QName.create(expectedModule, "leaf-grouping-X"), leafXinContainerV.getQName());
474         // grouping-V/container-grouping-V/leaf-grouping-Y
475         final LeafSchemaNode leafYinContainerV = (LeafSchemaNode) containerGroupingV.getDataChildByName(
476             QName.create(namespace, "leaf-grouping-Y"));
477         assertEquals(QName.create(expectedModule, "leaf-grouping-Y"), leafYinContainerV.getQName());
478
479         // grouping-X
480         childNodes = gx.getChildNodes();
481         assertEquals(2, childNodes.size());
482
483         // grouping-X/leaf-grouping-X
484         final LeafSchemaNode leafXinGX = (LeafSchemaNode) gx.getDataChildByName(
485             QName.create(namespace, "leaf-grouping-X"));
486         assertFalse(leafXinGX.isAddedByUses());
487         assertEquals(QName.create(expectedModule, "leaf-grouping-X"), leafXinGX.getQName());
488
489         // grouping-X/leaf-grouping-Y
490         final LeafSchemaNode leafYinGX = (LeafSchemaNode) gx.getDataChildByName(
491             QName.create(namespace, "leaf-grouping-Y"));
492         assertTrue(leafYinGX.isAddedByUses());
493         assertEquals(QName.create(expectedModule, "leaf-grouping-Y"), leafYinGX.getQName());
494
495         // grouping-Y
496         childNodes = gy.getChildNodes();
497         assertEquals(1, childNodes.size());
498
499         // grouping-Y/leaf-grouping-Y
500         final LeafSchemaNode leafYinGY = (LeafSchemaNode) gy.getDataChildByName(
501             QName.create(namespace, "leaf-grouping-Y"));
502         assertFalse(leafYinGY.isAddedByUses());
503         assertEquals(QName.create(expectedModule, "leaf-grouping-Y"), leafYinGY.getQName());
504
505         // grouping-Z
506         childNodes = gz.getChildNodes();
507         assertEquals(1, childNodes.size());
508
509         // grouping-Z/leaf-grouping-Z
510         final LeafSchemaNode leafZinGZ = (LeafSchemaNode) gz.getDataChildByName(
511             QName.create(namespace, "leaf-grouping-Z"));
512         assertFalse(leafZinGZ.isAddedByUses());
513         assertEquals(QName.create(expectedModule, "leaf-grouping-Z"), leafZinGZ.getQName());
514
515         // grouping-ZZ
516         childNodes = gzz.getChildNodes();
517         assertEquals(1, childNodes.size());
518
519         // grouping-ZZ/leaf-grouping-ZZ
520         final LeafSchemaNode leafZZinGZZ = (LeafSchemaNode) gzz.getDataChildByName(
521             QName.create(namespace, "leaf-grouping-ZZ"));
522         assertFalse(leafZZinGZZ.isAddedByUses());
523         assertEquals(QName.create(expectedModule, "leaf-grouping-ZZ"), leafZZinGZZ.getQName());
524
525         // TEST getOriginal from grouping-U
526         assertEquals(gv.getDataChildByName(QName.create(namespace, "leaf-grouping-V")),
527             extractOriginal(gu.getDataChildByName(QName.create(namespace, "leaf-grouping-V"))));
528         containerGroupingV = (ContainerSchemaNode) gu.getDataChildByName(
529             QName.create(namespace, "container-grouping-V"));
530         assertEquals(gv.getDataChildByName(QName.create(namespace, "container-grouping-V")),
531             extractOriginal(containerGroupingV));
532         assertEquals(gx.getDataChildByName(QName.create(namespace, "leaf-grouping-X")),
533             extractOriginal(containerGroupingV.getDataChildByName(QName.create(namespace, "leaf-grouping-X"))));
534         assertEquals(gy.getDataChildByName(QName.create(namespace, "leaf-grouping-Y")),
535             extractOriginal(containerGroupingV.getDataChildByName(QName.create(namespace, "leaf-grouping-Y"))));
536
537         assertEquals(gz.getDataChildByName(QName.create(namespace, "leaf-grouping-Z")),
538             extractOriginal(gu.getDataChildByName(QName.create(namespace, "leaf-grouping-Z"))));
539         assertEquals(gzz.getDataChildByName(QName.create(namespace, "leaf-grouping-ZZ")),
540             extractOriginal(gu.getDataChildByName(QName.create(namespace, "leaf-grouping-ZZ"))));
541
542         // TEST getOriginal from grouping-V
543         assertEquals(gz.getDataChildByName(QName.create(namespace, "leaf-grouping-Z")),
544             extractOriginal(gv.getDataChildByName(QName.create(namespace, "leaf-grouping-Z"))));
545         assertEquals(gzz.getDataChildByName(QName.create(namespace, "leaf-grouping-ZZ")),
546             extractOriginal(gv.getDataChildByName(QName.create(namespace, "leaf-grouping-ZZ"))));
547
548         // TEST getOriginal from grouping-X
549         assertEquals(gy.getDataChildByName(QName.create(namespace, "leaf-grouping-Y")),
550             extractOriginal(gx.getDataChildByName(QName.create(namespace, "leaf-grouping-Y"))));
551     }
552
553     @Test
554     public void testAddedByUsesLeafTypeQName() throws Exception {
555         final EffectiveModelContext loadModules = TestUtils.parseYangSources("/added-by-uses-leaf-test");
556         assertEquals(2, loadModules.getModules().size());
557
558         final Module foo = Iterables.getOnlyElement(loadModules.findModules("foo"));
559         final Module imp = Iterables.getOnlyElement(loadModules.findModules("import-module"));
560
561         final LeafSchemaNode leaf = (LeafSchemaNode)
562             ((ContainerSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(), "my-container")))
563             .getDataChildByName(QName.create(foo.getQNameModule(), "my-leaf"));
564
565         TypeDefinition<?> impType = null;
566         for (final TypeDefinition<?> typeDefinition : imp.getTypeDefinitions()) {
567             if (typeDefinition.getQName().getLocalName().equals("imp-type")) {
568                 impType = typeDefinition;
569                 break;
570             }
571         }
572
573         assertNotNull(impType);
574         assertEquals(leaf.getType().getQName(), impType.getQName());
575     }
576
577     private static void assertIsAddedByUses(final GroupingDefinition node, final boolean expected) {
578         assertEquals(expected, node.isAddedByUses());
579         for (DataSchemaNode child : node.getChildNodes()) {
580             assertIsAddedByUses(child, expected);
581         }
582     }
583
584     /**
585      * Check if node has addedByUses flag set to expected value. In case this is
586      * DataNodeContainer/ChoiceNode, check its child nodes/case nodes too.
587      *
588      * @param node node to check
589      * @param expected expected value
590      */
591     private static void assertIsAddedByUses(final DataSchemaNode node, final boolean expected) {
592         assertEquals(expected, node.isAddedByUses());
593         if (node instanceof DataNodeContainer) {
594             for (DataSchemaNode child : ((DataNodeContainer) node)
595                     .getChildNodes()) {
596                 assertIsAddedByUses(child, expected);
597             }
598         } else if (node instanceof ChoiceSchemaNode) {
599             for (CaseSchemaNode caseNode : ((ChoiceSchemaNode) node).getCases()) {
600                 assertIsAddedByUses(caseNode, expected);
601             }
602         }
603     }
604
605     private static @Nullable SchemaNode extractOriginal(final SchemaNode node) {
606         assertThat(node, instanceOf(DerivableSchemaNode.class));
607         return ((DerivableSchemaNode) node).getOriginal().orElse(null);
608     }
609 }