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