e3bf84065b42630b7b75ea0431af6158e7c5be80
[yangtools.git] / parser / yang-parser-rfc7950 / src / test / java / org / opendaylight / yangtools / yang / stmt / YangParserTest.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.CoreMatchers.startsWith;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertNotNull;
16 import static org.junit.Assert.assertNull;
17 import static org.junit.Assert.assertThrows;
18 import static org.junit.Assert.assertTrue;
19
20 import com.google.common.collect.Range;
21 import com.google.common.collect.RangeSet;
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.Set;
29 import org.junit.Test;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.common.Revision;
32 import org.opendaylight.yangtools.yang.common.XMLNamespace;
33 import org.opendaylight.yangtools.yang.common.YangVersion;
34 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.DeviateKind;
40 import org.opendaylight.yangtools.yang.model.api.Deviation;
41 import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
42 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
43 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
44 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
47 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
48 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
49 import org.opendaylight.yangtools.yang.model.api.Status;
50 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
51 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
52 import org.opendaylight.yangtools.yang.model.api.stmt.UnrecognizedStatement;
53 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
54 import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition;
55 import org.opendaylight.yangtools.yang.model.api.type.Int32TypeDefinition;
56 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
57 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
58 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
59 import org.opendaylight.yangtools.yang.model.api.type.TypeDefinitions;
60 import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
61 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
62 import org.opendaylight.yangtools.yang.model.ri.type.BaseTypes;
63 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
64 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
65
66 public class YangParserTest extends AbstractModelTest {
67     @Test
68     public void testHeaders() throws ParseException {
69         assertEquals("foo", FOO.getName());
70         assertEquals(YangVersion.VERSION_1, FOO.getYangVersion());
71         assertEquals(XMLNamespace.of("urn:opendaylight.foo"), FOO.getNamespace());
72         assertEquals("foo", FOO.getPrefix());
73
74         final Collection<? extends ModuleImport> imports = FOO.getImports();
75         assertEquals(2, imports.size());
76
77         final ModuleImport import2 = TestUtils.findImport(imports, "br");
78         assertEquals("bar", import2.getModuleName());
79         assertEquals(Revision.ofNullable("2013-07-03"), import2.getRevision());
80
81         final ModuleImport import3 = TestUtils.findImport(imports, "bz");
82         assertEquals("baz", import3.getModuleName());
83         assertEquals(Revision.ofNullable("2013-02-27"), import3.getRevision());
84
85         assertEquals(Optional.of("opendaylight"), FOO.getOrganization());
86         assertEquals(Optional.of("http://www.opendaylight.org/"), FOO.getContact());
87         assertEquals(Revision.ofNullable("2013-02-27"), FOO.getRevision());
88         assertFalse(FOO.getReference().isPresent());
89     }
90
91     @Test
92     public void testParseList() {
93         final ContainerSchemaNode interfaces = (ContainerSchemaNode) BAR.getDataChildByName(barQName("interfaces"));
94         final ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName(barQName("ifEntry"));
95         // test SchemaNode args
96         assertEquals(barQName("ifEntry"), ifEntry.getQName());
97
98         assertFalse(ifEntry.getDescription().isPresent());
99         assertFalse(ifEntry.getReference().isPresent());
100         assertEquals(Status.CURRENT, ifEntry.getStatus());
101         assertEquals(0, ifEntry.getUnknownSchemaNodes().size());
102         // test DataSchemaNode args
103         assertFalse(ifEntry.isAugmenting());
104         assertEquals(Optional.of(Boolean.TRUE), ifEntry.effectiveConfig());
105         // :TODO augment to ifEntry have when condition and so in consequence
106         // ifEntry should be a context node ?
107         // assertNull(constraints.getWhenCondition());
108         assertEquals(0, ifEntry.getMustConstraints().size());
109         ElementCountConstraint constraints = ifEntry.getElementCountConstraint().get();
110         assertEquals((Object) 1, constraints.getMinElements());
111         assertEquals((Object) 11, constraints.getMaxElements());
112         // test AugmentationTarget args
113         final Collection<? extends AugmentationSchemaNode> availableAugmentations = ifEntry.getAvailableAugmentations();
114         assertEquals(2, availableAugmentations.size());
115         // test ListSchemaNode args
116         final List<QName> expectedKey = new ArrayList<>();
117         expectedKey.add(barQName("ifIndex"));
118         assertEquals(expectedKey, ifEntry.getKeyDefinition());
119         assertFalse(ifEntry.isUserOrdered());
120         // test DataNodeContainer args
121         assertEquals(0, ifEntry.getTypeDefinitions().size());
122         assertEquals(4, ifEntry.getChildNodes().size());
123         assertEquals(0, ifEntry.getGroupings().size());
124         assertEquals(0, ifEntry.getUses().size());
125
126         final LeafSchemaNode ifIndex = (LeafSchemaNode) ifEntry.getDataChildByName(barQName("ifIndex"));
127         assertEquals(ifEntry.getKeyDefinition().get(0), ifIndex.getQName());
128         assertTrue(ifIndex.getType() instanceof Uint32TypeDefinition);
129         assertEquals(Optional.of("minutes"), ifIndex.getType().getUnits());
130         final LeafSchemaNode ifMtu = (LeafSchemaNode) ifEntry.getDataChildByName(barQName("ifMtu"));
131         assertEquals(BaseTypes.int32Type(), ifMtu.getType());
132     }
133
134     @Test
135     public void testTypedefRangesResolving() throws ParseException {
136         final LeafSchemaNode int32Leaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("int32-leaf"));
137
138         final Int32TypeDefinition leafType = (Int32TypeDefinition) int32Leaf.getType();
139         assertEquals(fooQName("int32-ext2"), leafType.getQName());
140         assertEquals(Optional.of("mile"), leafType.getUnits());
141         assertEquals(Optional.of("11"), leafType.getDefaultValue());
142
143         final RangeSet<? extends Number> rangeset = leafType.getRangeConstraint().get().getAllowedRanges();
144         final Set<? extends Range<? extends Number>> ranges = rangeset.asRanges();
145         assertEquals(1, ranges.size());
146
147         final Range<? extends Number> range = ranges.iterator().next();
148         assertEquals(12, range.lowerEndpoint().intValue());
149         assertEquals(20, range.upperEndpoint().intValue());
150
151         final Int32TypeDefinition firstBaseType = leafType.getBaseType();
152         assertEquals(barQName("int32-ext2"), firstBaseType.getQName());
153         assertEquals(Optional.of("mile"), firstBaseType.getUnits());
154         assertEquals(Optional.of("11"), firstBaseType.getDefaultValue());
155
156         final RangeSet<? extends Number> firstRangeset = firstBaseType.getRangeConstraint().get().getAllowedRanges();
157         final Set<? extends Range<? extends Number>> baseRanges = firstRangeset.asRanges();
158         assertEquals(2, baseRanges.size());
159
160         final Iterator<? extends Range<? extends Number>> it = baseRanges.iterator();
161         final Range<? extends Number> baseTypeRange1 = it.next();
162         assertEquals(3, baseTypeRange1.lowerEndpoint().intValue());
163         assertEquals(9, baseTypeRange1.upperEndpoint().intValue());
164         final Range<? extends Number> baseTypeRange2 = it.next();
165         assertEquals(11, baseTypeRange2.lowerEndpoint().intValue());
166         assertEquals(20, baseTypeRange2.upperEndpoint().intValue());
167
168         final Int32TypeDefinition secondBaseType = firstBaseType.getBaseType();
169         assertEquals(barQName("int32-ext1"), secondBaseType.getQName());
170         assertEquals(Optional.empty(), secondBaseType.getUnits());
171         assertEquals(Optional.empty(), secondBaseType.getDefaultValue());
172
173         final Set<? extends Range<? extends Number>> secondRanges = secondBaseType.getRangeConstraint().get()
174                 .getAllowedRanges().asRanges();
175         assertEquals(1, secondRanges.size());
176         final Range<? extends Number> secondRange = secondRanges.iterator().next();
177         assertEquals(2, secondRange.lowerEndpoint().intValue());
178         assertEquals(20, secondRange.upperEndpoint().intValue());
179
180         assertEquals(BaseTypes.int32Type(), secondBaseType.getBaseType());
181     }
182
183     @Test
184     public void testTypedefPatternsResolving() {
185         final LeafSchemaNode stringleaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("string-leaf"));
186
187         assertTrue(stringleaf.getType() instanceof StringTypeDefinition);
188         final StringTypeDefinition type = (StringTypeDefinition) stringleaf.getType();
189         assertEquals(barQName("string-ext4"), type.getQName());
190         assertEquals(Optional.empty(), type.getUnits());
191         assertEquals(Optional.empty(), type.getDefaultValue());
192         List<PatternConstraint> patterns = type.getPatternConstraints();
193         assertEquals(1, patterns.size());
194         PatternConstraint pattern = patterns.iterator().next();
195         assertEquals("^(?:[e-z]*)$", pattern.getJavaPatternString());
196         assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
197
198         final StringTypeDefinition baseType1 = type.getBaseType();
199         assertEquals(barQName("string-ext3"), baseType1.getQName());
200         assertEquals(Optional.empty(), baseType1.getUnits());
201         assertEquals(Optional.empty(), baseType1.getDefaultValue());
202         patterns = baseType1.getPatternConstraints();
203         assertEquals(1, patterns.size());
204         pattern = patterns.iterator().next();
205         assertEquals("^(?:[b-u]*)$", pattern.getJavaPatternString());
206         assertEquals(1, baseType1.getLengthConstraint().get().getAllowedRanges().asRanges().size());
207
208         final StringTypeDefinition baseType2 = baseType1.getBaseType();
209         assertEquals(barQName("string-ext2"), baseType2.getQName());
210         assertEquals(Optional.empty(), baseType2.getUnits());
211         assertEquals(Optional.empty(), baseType2.getDefaultValue());
212         assertTrue(baseType2.getPatternConstraints().isEmpty());
213         final RangeSet<Integer> baseType2Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
214         assertEquals(1, baseType2Lengths.asRanges().size());
215         Range<Integer> length = baseType2Lengths.span();
216         assertEquals(6, length.lowerEndpoint().intValue());
217         assertEquals(10, length.upperEndpoint().intValue());
218
219         final StringTypeDefinition baseType3 = baseType2.getBaseType();
220         assertEquals(barQName("string-ext1"), baseType3.getQName());
221         assertEquals(Optional.empty(), baseType3.getUnits());
222         assertEquals(Optional.empty(), baseType3.getDefaultValue());
223         patterns = baseType3.getPatternConstraints();
224         assertEquals(1, patterns.size());
225         pattern = patterns.iterator().next();
226         assertEquals("^(?:[a-k]*)$", pattern.getJavaPatternString());
227         final RangeSet<Integer> baseType3Lengths = baseType3.getLengthConstraint().get().getAllowedRanges();
228         assertEquals(1, baseType3Lengths.asRanges().size());
229         length = baseType3Lengths.span();
230         assertEquals(5, length.lowerEndpoint().intValue());
231         assertEquals(11, length.upperEndpoint().intValue());
232
233         assertEquals(BaseTypes.stringType(), baseType3.getBaseType());
234     }
235
236     @Test
237     public void testTypedefInvalidPatternsResolving() {
238         final LeafSchemaNode multiplePatternStringLeaf = (LeafSchemaNode) FOO.getDataChildByName(
239             fooQName("multiple-pattern-string-leaf"));
240         StringTypeDefinition type = (StringTypeDefinition) multiplePatternStringLeaf.getType();
241         assertEquals(barQName("multiple-pattern-string"), type.getQName());
242         assertEquals(Optional.empty(), type.getUnits());
243         assertEquals(Optional.empty(), type.getDefaultValue());
244         List<PatternConstraint> patterns = type.getPatternConstraints();
245         assertEquals(2, patterns.size());
246         assertEquals("^(?:[A-Z]*-%22!\\^\\^)$", patterns.get(0).getJavaPatternString());
247         assertEquals("^(?:[e-z]*)$", patterns.get(1).getJavaPatternString());
248         assertEquals(1, type.getLengthConstraint().get().getAllowedRanges().asRanges().size());
249
250         final LeafSchemaNode multiplePatternDirectStringDefLeaf = (LeafSchemaNode) FOO.getDataChildByName(
251             fooQName("multiple-pattern-direct-string-def-leaf"));
252         type = (StringTypeDefinition) multiplePatternDirectStringDefLeaf.getType();
253         assertEquals(fooQName("string"), type.getQName());
254         assertEquals(Optional.empty(), type.getUnits());
255         assertEquals(Optional.empty(), type.getDefaultValue());
256         patterns = type.getPatternConstraints();
257         assertEquals(3, patterns.size());
258
259         assertEquals("^(?:[e-z]*)$", patterns.get(0).getJavaPatternString());
260         assertEquals("^(?:[A-Z]*-%22!\\^\\^})$", patterns.get(1).getJavaPatternString());
261         assertEquals("^(?:[a-d]*)$", patterns.get(2).getJavaPatternString());
262     }
263
264     @Test
265     public void testTypedefLengthsResolving() {
266         final LeafSchemaNode lengthLeaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("length-leaf"));
267         final StringTypeDefinition type = (StringTypeDefinition) lengthLeaf.getType();
268
269         assertEquals(fooQName("string-ext2"), type.getQName());
270         assertEquals(Optional.empty(), type.getUnits());
271         assertEquals(Optional.empty(), type.getDefaultValue());
272         assertTrue(type.getPatternConstraints().isEmpty());
273         final RangeSet<Integer> typeLengths = type.getLengthConstraint().get().getAllowedRanges();
274         assertEquals(1, typeLengths.asRanges().size());
275         Range<Integer> length = typeLengths.span();
276         assertEquals(7, length.lowerEndpoint().intValue());
277         assertEquals(10, length.upperEndpoint().intValue());
278
279         final StringTypeDefinition baseType1 = type.getBaseType();
280         assertEquals(barQName("string-ext2"), baseType1.getQName());
281         assertEquals(Optional.empty(), baseType1.getUnits());
282         assertEquals(Optional.empty(), baseType1.getDefaultValue());
283         assertTrue(baseType1.getPatternConstraints().isEmpty());
284         final RangeSet<Integer> baseType2Lengths = baseType1.getLengthConstraint().get().getAllowedRanges();
285         assertEquals(1, baseType2Lengths.asRanges().size());
286         length = baseType2Lengths.span();
287         assertEquals(6, length.lowerEndpoint().intValue());
288         assertEquals(10, length.upperEndpoint().intValue());
289
290         final StringTypeDefinition baseType2 = baseType1.getBaseType();
291         assertEquals(barQName("string-ext1"), baseType2.getQName());
292         assertEquals(Optional.empty(), baseType2.getUnits());
293         assertEquals(Optional.empty(), baseType2.getDefaultValue());
294         final List<PatternConstraint> patterns = baseType2.getPatternConstraints();
295         assertEquals(1, patterns.size());
296         final PatternConstraint pattern = patterns.iterator().next();
297         assertEquals("^(?:[a-k]*)$", pattern.getJavaPatternString());
298         final RangeSet<Integer> baseType3Lengths = baseType2.getLengthConstraint().get().getAllowedRanges();
299         assertEquals(1, baseType3Lengths.asRanges().size());
300         length = baseType3Lengths.span();
301         assertEquals(5, length.lowerEndpoint().intValue());
302         assertEquals(11, length.upperEndpoint().intValue());
303
304         assertEquals(BaseTypes.stringType(), baseType2.getBaseType());
305     }
306
307     @Test
308     public void testTypedefDecimal1() {
309         final LeafSchemaNode testleaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("decimal-leaf"));
310
311         assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
312         final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
313         assertEquals(barQName("my-decimal-type"), type.getQName());
314         assertEquals(Optional.empty(), type.getUnits());
315         assertEquals(Optional.empty(), type.getDefaultValue());
316         assertEquals(6, type.getFractionDigits());
317         assertEquals(1, type.getRangeConstraint().get().getAllowedRanges().asRanges().size());
318
319         final DecimalTypeDefinition typeBase = type.getBaseType();
320         assertEquals(barQName("decimal64"), typeBase.getQName());
321         assertEquals(Optional.empty(), typeBase.getUnits());
322         assertEquals(Optional.empty(), typeBase.getDefaultValue());
323         assertEquals(6, typeBase.getFractionDigits());
324         assertEquals(1, typeBase.getRangeConstraint().get().getAllowedRanges().asRanges().size());
325
326         assertNull(typeBase.getBaseType());
327     }
328
329     @Test
330     public void testTypedefDecimal2() {
331         final LeafSchemaNode testleaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("decimal-leaf2"));
332
333         assertTrue(testleaf.getType() instanceof DecimalTypeDefinition);
334         final DecimalTypeDefinition type = (DecimalTypeDefinition) testleaf.getType();
335         assertEquals(barQName("my-decimal-type"), type.getQName());
336         assertEquals(Optional.empty(), type.getUnits());
337         assertEquals(Optional.empty(), type.getDefaultValue());
338         assertEquals(6, type.getFractionDigits());
339         assertEquals(1, type.getRangeConstraint().get().getAllowedRanges().asRanges().size());
340
341         final DecimalTypeDefinition baseTypeDecimal = type.getBaseType();
342         assertEquals(6, baseTypeDecimal.getFractionDigits());
343     }
344
345     @Test
346     public void testTypedefUnion() {
347         final LeafSchemaNode unionleaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("union-leaf"));
348
349         assertTrue(unionleaf.getType() instanceof UnionTypeDefinition);
350         final UnionTypeDefinition type = (UnionTypeDefinition) unionleaf.getType();
351         assertEquals(barQName("my-union-ext"), type.getQName());
352         assertEquals(Optional.empty(), type.getUnits());
353         assertEquals(Optional.empty(), type.getDefaultValue());
354
355         final UnionTypeDefinition baseType = type.getBaseType();
356         assertEquals(barQName("my-union"), baseType.getQName());
357         assertEquals(Optional.empty(), baseType.getUnits());
358         assertEquals(Optional.empty(), baseType.getDefaultValue());
359
360         final UnionTypeDefinition unionType = baseType.getBaseType();
361         final List<TypeDefinition<?>> unionTypes = unionType.getTypes();
362         assertEquals(2, unionTypes.size());
363
364         final Int16TypeDefinition unionType1 = (Int16TypeDefinition) unionTypes.get(0);
365         assertEquals(barQName("my-union"), baseType.getQName());
366         assertEquals(Optional.empty(), unionType1.getUnits());
367         assertEquals(Optional.empty(), unionType1.getDefaultValue());
368
369         final RangeConstraint<?> ranges = unionType1.getRangeConstraint().get();
370         assertEquals(1, ranges.getAllowedRanges().asRanges().size());
371         final Range<?> range = ranges.getAllowedRanges().span();
372         assertEquals((short)1, range.lowerEndpoint());
373         assertEquals((short)100, range.upperEndpoint());
374         assertEquals(BaseTypes.int16Type(), unionType1.getBaseType());
375
376         assertEquals(BaseTypes.int32Type(), unionTypes.get(1));
377     }
378
379     @Test
380     public void testNestedUnionResolving() {
381         final LeafSchemaNode testleaf = (LeafSchemaNode) FOO.getDataChildByName(fooQName("custom-union-leaf"));
382
383         assertTrue(testleaf.getType() instanceof UnionTypeDefinition);
384         final UnionTypeDefinition type = (UnionTypeDefinition) testleaf.getType();
385         assertEquals(bazQName("union1"), type.getQName());
386         assertEquals(Optional.empty(), type.getUnits());
387         assertEquals(Optional.empty(), type.getDefaultValue());
388
389         final UnionTypeDefinition typeBase = type.getBaseType();
390         assertEquals(bazQName("union2"), typeBase.getQName());
391         assertEquals(Optional.empty(), typeBase.getUnits());
392         assertEquals(Optional.empty(), typeBase.getDefaultValue());
393
394         final UnionTypeDefinition union = typeBase.getBaseType();
395         final List<TypeDefinition<?>> unionTypes = union.getTypes();
396         assertEquals(2, unionTypes.size());
397         assertEquals(BaseTypes.int32Type(), unionTypes.get(0));
398         assertTrue(unionTypes.get(1) instanceof UnionTypeDefinition);
399
400         final UnionTypeDefinition unionType1 = (UnionTypeDefinition) unionTypes.get(1);
401         assertEquals(barQName("nested-union2"), unionType1.getQName());
402         assertEquals(Optional.empty(), unionType1.getUnits());
403         assertEquals(Optional.empty(), unionType1.getDefaultValue());
404
405         final UnionTypeDefinition nestedUnion = unionType1.getBaseType();
406         final List<TypeDefinition<?>> nestedUnion2Types = nestedUnion.getTypes();
407         assertEquals(2, nestedUnion2Types.size());
408         assertTrue(nestedUnion2Types.get(1) instanceof StringTypeDefinition);
409         assertTrue(nestedUnion2Types.get(0) instanceof UnionTypeDefinition);
410
411         final UnionTypeDefinition myUnionExt = (UnionTypeDefinition) nestedUnion2Types.get(0);
412         assertEquals(barQName("my-union-ext"), myUnionExt.getQName());
413         assertEquals(Optional.empty(), myUnionExt.getUnits());
414         assertEquals(Optional.empty(), myUnionExt.getDefaultValue());
415
416
417         final UnionTypeDefinition myUnion = myUnionExt.getBaseType();
418         assertEquals(barQName("my-union"), myUnion.getQName());
419         assertEquals(Optional.empty(), myUnion.getUnits());
420         assertEquals(Optional.empty(), myUnion.getDefaultValue());
421
422         final UnionTypeDefinition myUnionBase = myUnion.getBaseType();
423         final List<TypeDefinition<?>> myUnionBaseTypes = myUnionBase.getTypes();
424         assertEquals(2, myUnionBaseTypes.size());
425         assertTrue(myUnionBaseTypes.get(0) instanceof Int16TypeDefinition);
426         assertEquals(BaseTypes.int32Type(), myUnionBaseTypes.get(1));
427
428         final Int16TypeDefinition int16Ext = (Int16TypeDefinition) myUnionBaseTypes.get(0);
429         assertEquals(TypeDefinitions.INT16, int16Ext.getQName());
430         assertEquals(Optional.empty(), int16Ext.getUnits());
431         assertEquals(Optional.empty(), int16Ext.getDefaultValue());
432         final Set<? extends Range<? extends Number>> ranges = int16Ext.getRangeConstraint().get().getAllowedRanges()
433                 .asRanges();
434         assertEquals(1, ranges.size());
435         final Range<? extends Number> range = ranges.iterator().next();
436         assertEquals(1, range.lowerEndpoint().intValue());
437         assertEquals(100, range.upperEndpoint().intValue());
438
439         assertEquals(BaseTypes.int16Type(), int16Ext.getBaseType());
440     }
441
442     @Test
443     public void testChoice() {
444         final ContainerSchemaNode transfer = (ContainerSchemaNode) FOO.getDataChildByName(fooQName("transfer"));
445         final ChoiceSchemaNode how = (ChoiceSchemaNode) transfer.getDataChildByName(fooQName("how"));
446         final Collection<? extends CaseSchemaNode> cases = how.getCases();
447         assertEquals(5, cases.size());
448         CaseSchemaNode input = null;
449         CaseSchemaNode output = null;
450         for (final CaseSchemaNode caseNode : cases) {
451             if ("input".equals(caseNode.getQName().getLocalName())) {
452                 input = caseNode;
453             } else if ("output".equals(caseNode.getQName().getLocalName())) {
454                 output = caseNode;
455             }
456         }
457         assertNotNull(input);
458         assertNotNull(output);
459     }
460
461     @Test
462     public void testDeviation() {
463         final Collection<? extends Deviation> deviations = FOO.getDeviations();
464         assertEquals(1, deviations.size());
465         final Deviation dev = deviations.iterator().next();
466         assertEquals(Optional.of("system/user ref"), dev.getReference());
467
468         assertEquals(Absolute.of(barQName("interfaces"), barQName("ifEntry")), dev.getTargetPath());
469         assertEquals(DeviateKind.ADD, dev.getDeviates().iterator().next().getDeviateType());
470     }
471
472     @Test
473     public void testUnknownNode() {
474         final ContainerSchemaNode network = (ContainerSchemaNode) BAZ.getDataChildByName(bazQName("network"));
475         final Collection<? extends UnrecognizedStatement> unknownNodes = network.asEffectiveStatement().getDeclared()
476             .declaredSubstatements(UnrecognizedStatement.class);
477         assertEquals(1, unknownNodes.size());
478         assertEquals("point", unknownNodes.iterator().next().argument());
479     }
480
481     @Test
482     public void testFeature() {
483         final Collection<? extends FeatureDefinition> features = BAZ.getFeatures();
484         assertEquals(3, features.size());
485     }
486
487     @Test
488     public void testExtension() {
489         final Collection<? extends ExtensionDefinition> extensions = BAZ.getExtensionSchemaNodes();
490         assertEquals(1, extensions.size());
491         final ExtensionDefinition extension = extensions.iterator().next();
492         assertEquals("name", extension.getArgument());
493         assertEquals(
494             Optional.of("Takes as argument a name string. Makes the code generator use the given name in the #define."),
495                 extension.getDescription());
496         assertTrue(extension.isYinElement());
497     }
498
499     @Test
500     public void testNotification() {
501         final Collection<? extends NotificationDefinition> notifications = BAZ.getNotifications();
502         assertEquals(1, notifications.size());
503
504         final NotificationDefinition notification = notifications.iterator().next();
505         // test SchemaNode args
506         assertEquals(bazQName("event"), notification.getQName());
507         assertFalse(notification.getDescription().isPresent());
508         assertFalse(notification.getReference().isPresent());
509         assertEquals(Status.CURRENT, notification.getStatus());
510         assertEquals(0, notification.getUnknownSchemaNodes().size());
511         // test DataNodeContainer args
512         assertEquals(0, notification.getTypeDefinitions().size());
513         assertEquals(3, notification.getChildNodes().size());
514         assertEquals(0, notification.getGroupings().size());
515         assertEquals(0, notification.getUses().size());
516
517         final LeafSchemaNode eventClass = (LeafSchemaNode) notification.getDataChildByName(bazQName("event-class"));
518         assertTrue(eventClass.getType() instanceof StringTypeDefinition);
519         final LeafSchemaNode severity = (LeafSchemaNode) notification.getDataChildByName(bazQName("severity"));
520         assertTrue(severity.getType() instanceof StringTypeDefinition);
521     }
522
523     @Test
524     public void testRpc() {
525         final Collection<? extends RpcDefinition> rpcs = BAZ.getRpcs();
526         assertEquals(1, rpcs.size());
527
528         final RpcDefinition rpc = rpcs.iterator().next();
529         assertEquals(Optional.of("Retrieve all or part of a specified configuration."), rpc.getDescription());
530         assertEquals(Optional.of("RFC 6241, Section 7.1"), rpc.getReference());
531     }
532
533     @Test
534     public void testTypePath() throws ParseException {
535         final Collection<? extends TypeDefinition<?>> types = BAR.getTypeDefinitions();
536
537         // int32-ext1
538         final Int32TypeDefinition int32ext1 = (Int32TypeDefinition) TestUtils.findTypedef(types, "int32-ext1");
539         assertEquals(barQName("int32-ext1"), int32ext1.getQName());
540
541         // int32-ext1/int32
542         assertEquals(BaseTypes.int32Type(), int32ext1.getBaseType());
543     }
544
545     @Test
546     public void testTypePath2() throws ParseException {
547         final Collection<? extends TypeDefinition<?>> types = BAR.getTypeDefinitions();
548
549         // my-decimal-type
550         final DecimalTypeDefinition myDecType = (DecimalTypeDefinition) TestUtils.findTypedef(types, "my-decimal-type");
551         assertEquals(barQName("my-decimal-type"), myDecType.getQName());
552
553         // my-base-int32-type/int32
554         assertEquals(barQName("decimal64"), myDecType.getBaseType().getQName());
555     }
556
557     @Test
558     public void testSubmodules() {
559         final DataSchemaNode id = FOO.getDataChildByName(fooQName("id"));
560         assertNotNull(id);
561         final DataSchemaNode subExt = FOO.getDataChildByName(fooQName("sub-ext"));
562         assertNotNull(subExt);
563         final DataSchemaNode subTransfer = FOO.getDataChildByName(fooQName("sub-transfer"));
564         assertNotNull(subTransfer);
565
566         assertEquals(2, FOO.getExtensionSchemaNodes().size());
567         assertEquals(2, FOO.getAugmentations().size());
568     }
569
570     @Test
571     public void unknownStatementInSubmoduleHeaderTest() throws Exception {
572         TestUtils.parseYangSource(
573             "/yang-grammar-test/revisions-extension.yang",
574             "/yang-grammar-test/submodule-header-extension.yang");
575     }
576
577     @Test
578     public void unknownStatementBetweenRevisionsTest() throws Exception {
579         TestUtils.parseYangSource(
580             "/yang-grammar-test/revisions-extension.yang",
581             "/yang-grammar-test/submodule-header-extension.yang");
582     }
583
584     @Test
585     public void unknownStatementsInStatementsTest() {
586         final var ex = assertThrows(SomeModifiersUnresolvedException.class,
587             () -> TestUtils.parseYangSource(
588                 "/yang-grammar-test/stmtsep-in-statements.yang",
589                 "/yang-grammar-test/stmtsep-in-statements2.yang",
590                 "/yang-grammar-test/stmtsep-in-statements-sub.yang"));
591         final var cause = ex.getCause();
592         assertThat(cause, instanceOf(SourceException.class));
593         assertThat(cause.getMessage(), startsWith("aaa is not a YANG statement or use of extension"));
594     }
595 }