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