Update TypeDefinition design
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / stmt / EffectiveStatementTypeTest.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
9 package org.opendaylight.yangtools.yang.stmt;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertTrue;
16 import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
17
18 import com.google.common.collect.Range;
19 import java.util.List;
20 import java.util.Optional;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.Module;
26 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
27 import org.opendaylight.yangtools.yang.model.api.Status;
28 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
29 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
30 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
31 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
32 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
33 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
34 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
35 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
37 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
39 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
41 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
42 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
43 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
44 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
45 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
46 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
47 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.LeafEffectiveStatementImpl;
48 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.BitsSpecificationEffectiveStatementImpl;
49 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Decimal64SpecificationEffectiveStatementImpl;
50 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.EnumSpecificationEffectiveStatementImpl;
51 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.IdentityRefSpecificationEffectiveStatementImpl;
52 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.LeafrefSpecificationEffectiveStatementImpl;
53 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.PatternConstraintEffectiveImpl;
54 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.UnionSpecificationEffectiveStatementImpl;
55
56 public class EffectiveStatementTypeTest {
57
58     private static final StatementStreamSource IMPORTED_MODULE = sourceForResource("/type-tests/types.yang");
59     private static SchemaContext effectiveSchemaContext;
60     private static Module types;
61
62     private LeafSchemaNode currentLeaf;
63
64     @BeforeClass
65     public static void setup() throws ReactorException {
66         final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
67         reactor.addSource(IMPORTED_MODULE);
68         effectiveSchemaContext = reactor.buildEffective();
69         types = effectiveSchemaContext.findModules("types").iterator().next();
70         assertNotNull(types);
71     }
72
73     @Test
74     public void testBinary() {
75         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-binary"));
76         assertNotNull(currentLeaf.getType());
77
78         final BinaryTypeDefinition binaryEff = (BinaryTypeDefinition)
79                 ((TypeEffectiveStatement<?>) ((LeafEffectiveStatementImpl) currentLeaf)
80                 .effectiveSubstatements().iterator().next()).getTypeDefinition();
81
82         assertNull(binaryEff.getBaseType());
83         assertEquals(Optional.empty(), binaryEff.getUnits());
84         assertEquals(Optional.empty(), binaryEff.getDefaultValue());
85         assertEquals("binary", binaryEff.getQName().getLocalName());
86         assertFalse(binaryEff.getLengthConstraint().isPresent());
87         assertEquals(Status.CURRENT, binaryEff.getStatus());
88         assertEquals("binary", binaryEff.getPath().getPathFromRoot().iterator().next().getLocalName());
89         assertNotNull(binaryEff.getUnknownSchemaNodes());
90         assertFalse(binaryEff.getDescription().isPresent());
91         assertFalse(binaryEff.getReference().isPresent());
92     }
93
94     @Test
95     public void testBits() {
96         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-bits"));
97         assertNotNull(currentLeaf.getType());
98
99         final List<BitsTypeDefinition.Bit> bitsEffIter = ((BitsTypeDefinition) currentLeaf.getType()).getBits();
100         final Bit bitEff = bitsEffIter.get(0);
101         final Bit bitEffSecond = bitsEffIter.get(1);
102
103         final BitsTypeDefinition bitsEff = ((BitsSpecificationEffectiveStatementImpl)
104                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
105                 .getTypeDefinition();
106
107         assertNull(bitsEff.getBaseType());
108         assertNotNull(bitsEff.getQName());
109         assertEquals("bits", bitsEff.getQName().getLocalName());
110         assertEquals("bits", bitsEff.getPath().getLastComponent().getLocalName());
111         assertNotNull(bitsEff.getUnknownSchemaNodes());
112         assertFalse(bitsEff.getDescription().isPresent());
113         assertFalse(bitsEff.getReference().isPresent());
114         assertEquals(Status.CURRENT, bitsEff.getStatus());
115         assertEquals(Optional.empty(), bitsEff.getUnits());
116         assertNotNull(bitsEff.toString());
117         assertNotNull(bitsEff.hashCode());
118         assertFalse(bitsEff.equals(null));
119         assertFalse(bitsEff.equals("test"));
120         assertTrue(bitsEff.equals(bitsEff));
121         assertEquals(3, bitsEff.getBits().size());
122         assertEquals(Optional.empty(), bitsEff.getDefaultValue());
123
124         assertNotNull(bitEff.getPath());
125         assertNotNull(bitEff.getUnknownSchemaNodes());
126         assertEquals(Optional.of("test bit"), bitEff.getDescription());
127         assertEquals(Optional.of("test bit ref"), bitEff.getReference());
128         assertEquals(Status.CURRENT, bitEff.getStatus());
129         assertNotNull(bitEff.hashCode());
130         assertFalse(bitEff.equals(null));
131         assertFalse(bitEff.equals("test"));
132         assertFalse(bitEff.equals(bitEffSecond));
133         assertNotNull(bitEff.toString());
134         assertEquals("one", bitEff.getName());
135         assertNotNull(bitEff.getQName());
136         assertEquals(0, bitEff.getPosition());
137     }
138
139     @Test
140     public void testBoolean() {
141         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-boolean"));
142         assertNotNull(currentLeaf.getType());
143         final BooleanTypeDefinition booleanEff = (BooleanTypeDefinition) ((TypeEffectiveStatement<?>)
144                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
145                 .getTypeDefinition();
146
147         assertNull(booleanEff.getBaseType());
148         assertEquals(Optional.empty(), booleanEff.getUnits());
149         assertEquals(Optional.empty(), booleanEff.getDefaultValue());
150         assertEquals("boolean", booleanEff.getQName().getLocalName());
151         assertNull(booleanEff.getPath().getParent().getParent());
152         assertNotNull(booleanEff.getUnknownSchemaNodes());
153         assertFalse(booleanEff.getDescription().isPresent());
154         assertFalse(booleanEff.getReference().isPresent());
155         assertEquals(Status.CURRENT, booleanEff.getStatus());
156         assertNotNull(booleanEff.toString());
157     }
158
159     @Test
160     public void testDecimal64() {
161         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-decimal64"));
162         assertNotNull(currentLeaf.getType());
163         final DecimalTypeDefinition decimal64Eff = ((Decimal64SpecificationEffectiveStatementImpl)
164                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
165                 .getTypeDefinition();
166
167         assertNull(decimal64Eff.getBaseType());
168         assertEquals(Optional.empty(), decimal64Eff.getUnits());
169         assertEquals(Optional.empty(), decimal64Eff.getDefaultValue());
170         assertEquals("decimal64", decimal64Eff.getQName().getLocalName());
171         assertNotNull(decimal64Eff.getUnknownSchemaNodes());
172
173         // FIXME: The yang model api is wrong: description/reference/status are not allowed under 'type', how come we
174         // parse it?
175         // allowed under 'type', how come we parse it?
176         assertFalse(decimal64Eff.getDescription().isPresent());
177         assertFalse(decimal64Eff.getReference().isPresent());
178         assertEquals(Status.CURRENT, decimal64Eff.getStatus());
179
180         assertEquals(3, decimal64Eff.getRangeConstraints().size());
181         assertNotNull(decimal64Eff.toString());
182         assertNotNull(decimal64Eff.hashCode());
183         assertTrue(decimal64Eff.getFractionDigits().equals(2));
184         assertFalse(decimal64Eff.equals(null));
185         assertFalse(decimal64Eff.equals("test"));
186         assertTrue(decimal64Eff.equals(decimal64Eff));
187         assertEquals("decimal64", decimal64Eff.getPath().getLastComponent().getLocalName());
188     }
189
190     @Test
191     public void testEmpty() {
192         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-empty"));
193         assertNotNull(currentLeaf.getType());
194         final EmptyTypeDefinition emptyEff = (EmptyTypeDefinition) ((TypeEffectiveStatement<?>)
195                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
196                 .getTypeDefinition();
197
198         assertEquals(Optional.empty(), emptyEff.getUnits());
199         assertEquals(Optional.empty(), emptyEff.getDefaultValue());
200         assertNull(emptyEff.getBaseType());
201         assertEquals("empty", emptyEff.getQName().getLocalName());
202         assertNull(emptyEff.getPath().getParent().getParent());
203         assertNotNull(emptyEff.getUnknownSchemaNodes());
204         assertFalse(emptyEff.getDescription().isPresent());
205         assertFalse(emptyEff.getReference().isPresent());
206         assertEquals("CURRENT", emptyEff.getStatus().toString());
207         assertNotNull(emptyEff.toString());
208     }
209
210     @Test
211     public void testEnum() {
212         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-enum"));
213         assertNotNull(currentLeaf.getType());
214         final List<EnumTypeDefinition.EnumPair> enumEffIter = ((EnumTypeDefinition) currentLeaf.getType()).getValues();
215         final EnumPair enumEff = enumEffIter.iterator().next();
216
217         final EnumTypeDefinition enumSpecEff = ((EnumSpecificationEffectiveStatementImpl)
218                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
219                 .getTypeDefinition();
220
221         assertEquals("enumeration", enumSpecEff.getQName().getLocalName());
222         assertEquals("enumeration", enumSpecEff.getPath().getLastComponent().getLocalName());
223         assertEquals(Optional.empty(), enumSpecEff.getDefaultValue());
224         assertEquals(3, enumSpecEff.getValues().size());
225         assertNull(enumSpecEff.getBaseType());
226         assertNotNull(enumSpecEff.getUnknownSchemaNodes());
227         assertEquals(Status.CURRENT, enumSpecEff.getStatus());
228         assertFalse(enumSpecEff.getDescription().isPresent());
229         assertFalse(enumSpecEff.getReference().isPresent());
230         assertEquals(Optional.empty(), enumSpecEff.getUnits());
231         assertNotNull(enumSpecEff.toString());
232         assertNotNull(enumSpecEff.hashCode());
233         assertFalse(enumSpecEff.equals(null));
234         assertFalse(enumSpecEff.equals("test"));
235         assertTrue(enumSpecEff.equals(enumSpecEff));
236
237         assertEquals("zero", enumEff.getName());
238         assertNotNull(enumEff.getUnknownSchemaNodes());
239         assertEquals(Optional.of("test enum"), enumEff.getDescription());
240         assertEquals(Optional.of("test enum ref"), enumEff.getReference());
241         assertEquals(Status.CURRENT, enumEff.getStatus());
242         assertEquals(0, enumEff.getValue());
243     }
244
245     @Test
246     public void testIdentityRef() {
247         currentLeaf = (LeafSchemaNode) types
248                 .getDataChildByName(QName.create(types.getQNameModule(), "leaf-identityref"));
249         assertNotNull(currentLeaf.getType());
250         final IdentityrefTypeDefinition identityRefEff = ((IdentityRefSpecificationEffectiveStatementImpl)
251                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
252                 .getTypeDefinition();
253
254         assertEquals(Optional.empty(), identityRefEff.getDefaultValue());
255         assertEquals("identityref", identityRefEff.getQName().getLocalName());
256         assertEquals("identityref", identityRefEff.getPath().getLastComponent().getLocalName());
257         assertNull(identityRefEff.getBaseType());
258         assertNotNull(identityRefEff.getUnknownSchemaNodes());
259         assertEquals(Status.CURRENT, identityRefEff.getStatus());
260         assertEquals("test-identity", identityRefEff.getIdentity().getQName().getLocalName());
261         assertFalse(identityRefEff.getDescription().isPresent());
262         assertFalse(identityRefEff.getReference().isPresent());
263         assertNotNull(identityRefEff.toString());
264
265         // FIXME: the model is wrong, but we accept units in 'type' statement
266         assertEquals(Optional.empty(), identityRefEff.getUnits());
267     }
268
269     @Test
270     public void testInstanceIdentifier() {
271         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
272                 "leaf-instance-identifier"));
273         assertNotNull(currentLeaf.getType());
274         final InstanceIdentifierTypeDefinition instanceIdentEff = (InstanceIdentifierTypeDefinition)
275                 ((TypeEffectiveStatement<?>) ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements()
276                         .iterator().next()).getTypeDefinition();
277         assertNotNull(instanceIdentEff.toString());
278
279         assertFalse(instanceIdentEff.requireInstance());
280         assertEquals("instance-identifier", instanceIdentEff.getQName().getLocalName());
281         assertEquals("instance-identifier", instanceIdentEff.getPath().getLastComponent().getLocalName());
282         assertNull(instanceIdentEff.getBaseType());
283         assertEquals(Optional.empty(), instanceIdentEff.getDefaultValue());
284         assertNotNull(instanceIdentEff.getUnknownSchemaNodes());
285         assertFalse(instanceIdentEff.getDescription().isPresent());
286         assertFalse(instanceIdentEff.getReference().isPresent());
287         assertEquals(Optional.empty(), instanceIdentEff.getUnits());
288         assertEquals(Status.CURRENT, instanceIdentEff.getStatus());
289         assertNotNull(instanceIdentEff.hashCode());
290         assertFalse(instanceIdentEff.equals(null));
291         assertFalse(instanceIdentEff.equals("test"));
292         assertTrue(instanceIdentEff.equals(instanceIdentEff));
293     }
294
295     @Test
296     public void testLeafref() {
297         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-leafref"));
298         assertNotNull(currentLeaf.getType());
299
300         final LeafrefTypeDefinition leafrefEff = ((LeafrefSpecificationEffectiveStatementImpl)
301                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
302                 .getTypeDefinition();
303
304         assertEquals("/container-test/leaf-test", leafrefEff.getPathStatement().toString());
305         assertNull(leafrefEff.getBaseType());
306         assertEquals(Optional.empty(), leafrefEff.getUnits());
307         assertEquals(Optional.empty(), leafrefEff.getDefaultValue());
308         assertNotNull(leafrefEff.toString());
309         assertEquals("leafref", leafrefEff.getQName().getLocalName());
310         assertEquals(Status.CURRENT, leafrefEff.getStatus());
311         assertNotNull(leafrefEff.getUnknownSchemaNodes());
312         assertEquals("leafref", leafrefEff.getPath().getLastComponent().getLocalName());
313         assertFalse(leafrefEff.getDescription().isPresent());
314         assertFalse(leafrefEff.getReference().isPresent());
315         assertNotNull(leafrefEff.hashCode());
316         assertFalse(leafrefEff.equals(null));
317         assertFalse(leafrefEff.equals("test"));
318         assertTrue(leafrefEff.equals(leafrefEff));
319     }
320
321     @Test
322     public void testIntAll() {
323         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-int8"));
324         assertNotNull(currentLeaf.getType());
325         final TypeEffectiveStatement<?> int8Eff = (TypeEffectiveStatement<?>)
326                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
327         assertNotNull(int8Eff.toString());
328
329         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-int16"));
330         assertNotNull(currentLeaf.getType());
331         final TypeEffectiveStatement<?> int16Eff = (TypeEffectiveStatement<?>)
332                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
333         assertNotNull(int16Eff.toString());
334
335         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-int32"));
336         assertNotNull(currentLeaf.getType());
337         final TypeEffectiveStatement<?> int32Eff = (TypeEffectiveStatement<?>)
338                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
339         assertNotNull(int32Eff.toString());
340
341         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-int64"));
342         assertNotNull(currentLeaf.getType());
343         final TypeEffectiveStatement<?> int64Eff = (TypeEffectiveStatement<?>)
344                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
345         assertNotNull(int64Eff.toString());
346
347         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-uint8"));
348         assertNotNull(currentLeaf.getType());
349         final TypeEffectiveStatement<?> uint8Eff = (TypeEffectiveStatement<?>)
350                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
351         assertNotNull(uint8Eff.toString());
352
353         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-uint16"));
354         assertNotNull(currentLeaf.getType());
355         final TypeEffectiveStatement<?> uint16Eff = (TypeEffectiveStatement<?>)
356                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
357         assertNotNull(uint16Eff.toString());
358
359         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-uint32"));
360         assertNotNull(currentLeaf.getType());
361         final TypeEffectiveStatement<?> uint32Eff = (TypeEffectiveStatement<?>)
362                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
363         assertNotNull(uint32Eff.toString());
364
365         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-uint64"));
366         assertNotNull(currentLeaf.getType());
367         final TypeEffectiveStatement<?> uint64Eff = (TypeEffectiveStatement<?>)
368                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next();
369         assertNotNull(uint64Eff.toString());
370     }
371
372     @Test
373     public void testUnion() {
374         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-union"));
375         assertNotNull(currentLeaf.getType());
376         final UnionTypeDefinition unionEff = ((UnionSpecificationEffectiveStatementImpl)
377                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
378                 .getTypeDefinition();
379
380         assertEquals(2, unionEff.getTypes().size());
381         assertEquals("union", unionEff.getQName().getLocalName());
382         assertEquals("CURRENT", unionEff.getStatus().toString());
383         assertNotNull(unionEff.getUnknownSchemaNodes());
384         assertNull(unionEff.getBaseType());
385         assertEquals(Optional.empty(), unionEff.getUnits());
386         assertEquals(Optional.empty(), unionEff.getDefaultValue());
387         assertFalse(unionEff.getDescription().isPresent());
388         assertFalse(unionEff.getReference().isPresent());
389         assertNotNull(unionEff.toString());
390         assertNotNull(unionEff.hashCode());
391         assertFalse(unionEff.equals(null));
392         assertFalse(unionEff.equals("test"));
393         assertTrue(unionEff.equals(unionEff));
394         assertEquals("union", unionEff.getPath().getLastComponent().getLocalName());
395     }
396
397     @Test
398     public void testLengthConstraint() {
399         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
400                 "leaf-length-pattern"));
401
402         final StringTypeDefinition leafType = (StringTypeDefinition) currentLeaf.getType();
403         assertNotNull(leafType);
404         final LengthConstraint lengthConstraint = leafType.getLengthConstraint().get();
405
406         final Range<Integer> span = lengthConstraint.getAllowedRanges().span();
407         assertEquals(1, span.lowerEndpoint().intValue());
408         assertEquals(255, span.upperEndpoint().intValue());
409         assertFalse(lengthConstraint.getReference().isPresent());
410         assertFalse(lengthConstraint.getDescription().isPresent());
411         assertFalse(lengthConstraint.getErrorMessage().isPresent());
412         assertFalse(lengthConstraint.getErrorAppTag().isPresent());
413         assertNotNull(lengthConstraint.toString());
414         assertNotNull(lengthConstraint.hashCode());
415         assertFalse(lengthConstraint.equals(null));
416         assertFalse(lengthConstraint.equals("test"));
417
418         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
419                 "leaf-length-pattern-second"));
420         assertNotNull(currentLeaf.getType());
421         final LengthConstraint lengthConstraintSecond = ((StringTypeDefinition) currentLeaf.getType())
422                 .getLengthConstraint().get();
423         assertFalse(lengthConstraint.equals(lengthConstraintSecond));
424     }
425
426     @Test
427     public void testPatternConstraint() {
428         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
429                 "leaf-length-pattern"));
430         assertNotNull(currentLeaf.getType());
431         final PatternConstraintEffectiveImpl patternConstraint = (PatternConstraintEffectiveImpl)
432                 ((StringTypeDefinition) currentLeaf.getType()).getPatternConstraints().get(0);
433         final PatternConstraintEffectiveImpl patternConstraintThird = (PatternConstraintEffectiveImpl)
434                 ((StringTypeDefinition) currentLeaf.getType()).getPatternConstraints().get(0);
435         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(),
436                 "leaf-length-pattern-second"));
437         assertNotNull(currentLeaf.getType());
438         final PatternConstraintEffectiveImpl patternConstraintSecond = (PatternConstraintEffectiveImpl)
439                 ((StringTypeDefinition) currentLeaf.getType()).getPatternConstraints().get(0);
440
441         assertEquals("^[0-9a-fA-F]*$", patternConstraint.getJavaPatternString());
442         assertFalse(patternConstraint.getReference().isPresent());
443         assertFalse(patternConstraint.getDescription().isPresent());
444         assertEquals(Optional.of("Supplied value does not match the regular expression ^[0-9a-fA-F]*$."),
445             patternConstraint.getErrorMessage());
446         assertEquals(Optional.of("invalid-regular-expression"), patternConstraint.getErrorAppTag());
447         assertNotNull(patternConstraint.toString());
448         assertNotNull(patternConstraint.hashCode());
449         assertFalse(patternConstraint.equals(null));
450         assertFalse(patternConstraint.equals("test"));
451         assertFalse(patternConstraint.equals(patternConstraintSecond));
452         assertTrue(patternConstraint.equals(patternConstraintThird));
453     }
454
455     @Test
456     public void testString() {
457         currentLeaf = (LeafSchemaNode) types.getDataChildByName(QName.create(types.getQNameModule(), "leaf-string"));
458         assertNotNull(currentLeaf.getType());
459         final StringTypeDefinition stringEff = (StringTypeDefinition) ((TypeEffectiveStatement<?>)
460                 ((LeafEffectiveStatementImpl) currentLeaf).effectiveSubstatements().iterator().next())
461                 .getTypeDefinition();
462
463         assertEquals("string", stringEff.getQName().getLocalName());
464         assertEquals(Status.CURRENT, stringEff.getStatus());
465         assertEquals(Optional.empty(), stringEff.getUnits());
466         assertEquals(Optional.empty(), stringEff.getDefaultValue());
467         assertNotNull(stringEff.getUnknownSchemaNodes());
468         assertNull(stringEff.getBaseType());
469         assertFalse(stringEff.getDescription().isPresent());
470         assertFalse(stringEff.getReference().isPresent());
471         assertNotNull(stringEff.toString());
472         assertNotNull(stringEff.hashCode());
473         assertFalse(stringEff.equals(null));
474         assertFalse(stringEff.equals("test"));
475         assertTrue(stringEff.equals(stringEff));
476         assertEquals("string", stringEff.getPath().getLastComponent().getLocalName());
477         assertFalse(stringEff.getLengthConstraint().isPresent());
478         assertNotNull(stringEff.getPatternConstraints());
479     }
480 }