Refactor GeneratedTypeBuilderImpl
[mdsal.git] / binding / mdsal-binding-generator-util / src / test / java / org / opendaylight / mdsal / binding / model / util / BindingGeneratorUtilTest.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.mdsal.binding.model.util;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotEquals;
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.junit.Assert.fail;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.mock;
19
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.common.collect.Range;
23 import java.io.Serializable;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.Set;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.opendaylight.mdsal.binding.model.api.AccessModifier;
31 import org.opendaylight.mdsal.binding.model.api.Restrictions;
32 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
33 import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder;
34 import org.opendaylight.mdsal.binding.model.util.generated.type.builder.CodegenGeneratedTypeBuilder;
35 import org.opendaylight.yangtools.yang.binding.BindingMapping;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
38 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Module;
40 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
41 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
42 import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange;
43 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
46 import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
47 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
48 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
49 import org.opendaylight.yangtools.yang.model.util.type.DerivedTypes;
50 import org.opendaylight.yangtools.yang.model.util.type.InvalidLengthConstraintException;
51 import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes;
52 import org.opendaylight.yangtools.yang.model.util.type.StringTypeBuilder;
53 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
54
55 public class BindingGeneratorUtilTest {
56     private static final SchemaPath ROOT_PATH = SchemaPath.create(true, QName.create("test", "/root"));
57
58     @Rule
59     public ExpectedException expectedEx = ExpectedException.none();
60
61     /**
62      * Tests methods:
63      * <ul>
64      * <li>moduleNamespaceToPackageName</li> - with revision
65      * <li>packageNameForGeneratedType</li>
66      * <ul>
67      * <li>validateJavaPackage</li>
68      * </ul>
69      * <li>packageNameForTypeDefinition</li> <li>moduleNamespaceToPackageName</li>
70      * - without revision </ul>
71      */
72     @Test
73     public void testBindingGeneratorUtilMethods() {
74         final Set<Module> modules = YangParserTestUtils.parseYangResources(BindingGeneratorUtilTest.class,
75             "/module.yang").getModules();
76         String packageName = "";
77         Module module = null;
78         for (Module m : modules) {
79             module = m;
80             break;
81         }
82         assertNotNull("Module can't be null", module);
83
84         // test of the method moduleNamespaceToPackageName()
85         packageName = BindingMapping.getRootPackageName(module.getQNameModule());
86         assertEquals("Generated package name is incorrect.",
87                 "org.opendaylight.yang.gen.v1.urn.m.o.d.u.l.e.n.a.m.e.t.e.s.t._case._1digit.rev130910", packageName);
88
89         // test of the method packageNameForGeneratedType()
90         DataNodeIterator it = new DataNodeIterator(module);
91         List<ContainerSchemaNode> schemaContainers = it.allContainers();
92         String subPackageNameForDataNode = "";
93         for (ContainerSchemaNode containerSchemaNode : schemaContainers) {
94             if (containerSchemaNode.getQName().getLocalName().equals("cont-inner")) {
95                 subPackageNameForDataNode = BindingGeneratorUtil.packageNameForGeneratedType(packageName,
96                         containerSchemaNode.getPath());
97                 break;
98             }
99         }
100         assertEquals("The name of the subpackage is incorrect.",
101                 "org.opendaylight.yang.gen.v1.urn.m.o.d.u.l.e.n.a.m.e.t.e.s.t._case._1digit.rev130910.cont.outter",
102                 subPackageNameForDataNode);
103
104         // test of the method packageNameForTypeDefinition
105         Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
106         String subPackageNameForTypeDefinition = "";
107         TypeDefinition<?> firstTypeDef = null;
108
109         for (TypeDefinition<?> tpDef : typeDefinitions) {
110             if (tpDef.getQName().getLocalName().equals("tpdf")) {
111                 subPackageNameForTypeDefinition = BindingGeneratorUtil.packageNameForTypeDefinition(packageName, tpDef);
112                 firstTypeDef = tpDef;
113                 break;
114             }
115         }
116         assertEquals("The name of the subpackage is incorrect.",
117                 "org.opendaylight.yang.gen.v1.urn.m.o.d.u.l.e.n.a.m.e.t.e.s.t._case._1digit.rev130910",
118                 subPackageNameForTypeDefinition);
119
120         // test method getRestrictions
121         Restrictions restriction = BindingGeneratorUtil.getRestrictions(firstTypeDef);
122         assertNotNull(restriction);
123
124         // test method computeDefaultSUID
125         GeneratedTypeBuilder genTypeBuilder = new CodegenGeneratedTypeBuilder("org.opendaylight.yangtools.test", "TestType");
126         genTypeBuilder.addMethod("testMethod");
127         genTypeBuilder.addAnnotation("org.opendaylight.yangtools.test.annotation", "AnnotationTest");
128         genTypeBuilder.addEnclosingTransferObject("testObject");
129         genTypeBuilder.addProperty("newProp");
130         GeneratedTypeBuilder genType = new CodegenGeneratedTypeBuilder("org.opendaylight.yangtools.test", "Type2");
131         genTypeBuilder.addImplementsType(genType);
132         long computedSUID = BindingGeneratorUtil.computeDefaultSUID(genTypeBuilder);
133
134         GeneratedTypeBuilder genTypeBuilder2 = new CodegenGeneratedTypeBuilder("org.opendaylight.yangtools.test2", "TestType2");
135         long computedSUID2 = BindingGeneratorUtil.computeDefaultSUID(genTypeBuilder2);
136         assertNotEquals(computedSUID, computedSUID2);
137
138         // test of exception part of the method moduleNamespaceToPackageName()
139         Module moduleWithoutRevision = mock(Module.class);
140         doReturn(null).when(moduleWithoutRevision).getQNameModule();
141         try {
142             BindingGeneratorUtil.moduleNamespaceToPackageName(moduleWithoutRevision);
143             fail("Expected IllegalArgumentException");
144         } catch (IllegalArgumentException e) {
145         }
146     }
147
148     /**
149      * Test for the method
150      * &lt;ul&gt;
151      * &lt;li&gt;{@link BindingGeneratorUtil#packageNameForTypeDefinition(String, TypeDefinition)
152      * packageNameForTypeDefinition(String, TypeDefinition)}&lt;/li&gt;
153      * &lt;/ul&gt;
154      */
155     @Test
156     @Deprecated
157     public void testPackageNameForTypeDefinitionNullBasePackageName() {
158         expectedEx.expect(IllegalArgumentException.class);
159         expectedEx.expectMessage("Base Package Name cannot be NULL!");
160         BindingGeneratorUtil.packageNameForTypeDefinition(null, null);
161     }
162
163     /**
164      * Test for the method
165      * &lt;ul&gt;
166      * &lt;li&gt;{@link BindingGeneratorUtil#packageNameForTypeDefinition(String, TypeDefinition)
167      * packageNameForTypeDefinition(String, TypeDefinition)}&lt;/li&gt;
168      * &lt;/ul&gt;
169      */
170     @Test
171     @Deprecated
172     public void testPackageNameForTypeDefinitionNullTypeDefinition() {
173         expectedEx.expect(IllegalArgumentException.class);
174         expectedEx.expectMessage("Type Definition reference cannot be NULL!");
175         BindingGeneratorUtil.packageNameForTypeDefinition("test.package", null);
176     }
177
178     /**
179      * Test for the method
180      * &lt;ul&gt;
181      * &lt;li&gt;{@link BindingGeneratorUtil#packageNameForGeneratedType(String, SchemaPath)
182      * packageNameForGeneratedType(String, SchemaPath)}&lt;/li&gt;
183      * &lt;/ul&gt;
184      */
185     @Test
186     public void testPackageNameForGeneratedTypeNullBasePackageName() {
187         expectedEx.expect(NullPointerException.class);
188         BindingGeneratorUtil.packageNameForGeneratedType(null, null);
189     }
190
191     /**
192      * Test for the method
193      * &lt;ul&gt;
194      * &lt;li&gt;{@link BindingGeneratorUtil#packageNameForGeneratedType(String, SchemaPath)
195      * packageNameForGeneratedType(String, SchemaPath)}&lt;/li&gt;
196      * &lt;/ul&gt;
197      */
198     @Test
199     public void testPackageNameForGeneratedTypeNullSchemaPath() {
200         expectedEx.expect(NullPointerException.class);
201         BindingGeneratorUtil.packageNameForGeneratedType("test.package", null);
202     }
203
204     /**
205      * Test for the method
206      * &lt;ul&gt;
207      * &lt;li&gt;{@link BindingGeneratorUtil#parseToClassName(String)
208      * parseToClassName(String)}&lt;/li&gt;
209      * &lt;/ul&gt;
210      */
211     @Test
212     public void testParseToClassNameNullValue() {
213         String className = BindingGeneratorUtil.parseToClassName("test-class-name");
214         assertEquals("TestClassName", className);
215
216         expectedEx.expect(IllegalArgumentException.class);
217         expectedEx.expectMessage("Name can not be null");
218         className = BindingGeneratorUtil.parseToClassName(null);
219     }
220
221     /**
222      * Test for the method
223      * &lt;ul&gt;
224      * &lt;li&gt;{@link BindingGeneratorUtil#parseToClassName(String)
225      * parseToClassName(String)}&lt;/li&gt;
226      * &lt;/ul&gt;
227      */
228     @Test
229     public void testParseToClassNameEmptyValue() {
230         String className = BindingGeneratorUtil.parseToClassName("test-class-name");
231         assertEquals("TestClassName", className);
232
233         expectedEx.expect(IllegalArgumentException.class);
234         expectedEx.expectMessage("Name can not be empty");
235         className = BindingGeneratorUtil.parseToClassName("");
236     }
237
238     /**
239      * Test for the method
240      * &lt;ul&gt;
241      * &lt;li&gt;{@link BindingGeneratorUtil#resolveJavaReservedWordEquivalency(String)
242      * resolveJavaReservedWordEquivalency(String)}&lt;/li&gt;
243      * &lt;ul&gt;
244      */
245     @Test
246     public void testValidateParameterName() {
247         assertNull("Return value is incorrect.", BindingGeneratorUtil.resolveJavaReservedWordEquivalency(null));
248         assertEquals("Return value is incorrect.", "whatever",
249                 BindingGeneratorUtil.resolveJavaReservedWordEquivalency("whatever"));
250         assertEquals("Return value is incorrect.", "_case",
251                 BindingGeneratorUtil.resolveJavaReservedWordEquivalency("case"));
252     }
253
254     /**
255      * Tests the methods:
256      * &lt;ul&gt;
257      * &lt;li&gt;parseToClassName&lt;/li&gt;
258      * &lt;ul&gt;
259      * &lt;li&gt;parseToCamelCase&lt;/li&gt;
260      * &lt;ul&gt;
261      * &lt;li&gt;replaceWithCamelCase&lt;/li&gt;
262      * &lt;/ul&gt;
263      * &lt;/ul&gt; &lt;li&gt;parseToValidParamName&lt;/li&gt;
264      * &lt;ul&gt;
265      * &lt;li&gt;parseToCamelCase&lt;/li&gt;
266      * &lt;ul&gt;
267      * &lt;li&gt;replaceWithCamelCase&lt;/li&gt;
268      * &lt;/ul&gt;
269      * &lt;/ul&gt;
270      * &lt;ul&gt;
271      */
272     @Test
273     public void testParsingMethods() {
274         // parseToClassName method testing
275         assertEquals("Class name has incorrect format", "SomeTestingClassName",
276                 BindingMapping.getClassName("  some-testing_class name   "));
277         assertEquals("Class name has incorrect format", "_0SomeTestingClassName",
278                 BindingMapping.getClassName("  0 some-testing_class name   "));
279
280         // parseToValidParamName
281         assertEquals("Parameter name has incorrect format", "someTestingParameterName",
282                 BindingGeneratorUtil.parseToValidParamName("  some-testing_parameter   name   "));
283         assertEquals("Parameter name has incorrect format", "_0someTestingParameterName",
284                 BindingGeneratorUtil.parseToValidParamName("  0some-testing_parameter   name   "));
285     }
286
287     @Test
288     public void computeDefaultSUIDTest() {
289         CodegenGeneratedTypeBuilder generatedTypeBuilder = new CodegenGeneratedTypeBuilder("my.package", "MyName");
290
291         MethodSignatureBuilder method = generatedTypeBuilder.addMethod("myMethodName");
292         method.setAccessModifier(AccessModifier.PUBLIC);
293         generatedTypeBuilder.addProperty("myProperty");
294         generatedTypeBuilder.addImplementsType(Types.typeForClass(Serializable.class));
295
296         assertEquals(6788238694991761868L, BindingGeneratorUtil.computeDefaultSUID(generatedTypeBuilder));
297
298     }
299
300     @Test
301     public void getRestrictionsTest() throws InvalidLengthConstraintException {
302         final Optional<String> absent = Optional.empty();
303         final StringTypeBuilder builder =
304                 RestrictedTypes.newStringBuilder(BaseTypes.stringType(), ROOT_PATH);
305
306         builder.addPatternConstraint(BaseConstraints.newPatternConstraint(".*", absent, absent));
307         builder.setLengthConstraint(mock(ConstraintMetaDefinition.class), ImmutableList.of(ValueRange.of(1, 2)));
308
309         Restrictions restrictions = BindingGeneratorUtil.getRestrictions(builder.build());
310
311         assertNotNull(restrictions);
312         assertEquals(ImmutableSet.of(Range.closed(1, 2)),
313             restrictions.getLengthConstraint().get().getAllowedRanges().asRanges());
314         assertFalse(restrictions.getRangeConstraint().isPresent());
315         assertEquals(1, restrictions.getPatternConstraints().size());
316
317         assertFalse(restrictions.isEmpty());
318         assertTrue(restrictions.getPatternConstraints().contains(
319                 BaseConstraints.newPatternConstraint(".*", absent, absent)));
320     }
321
322     @Test
323     public void getEmptyRestrictionsTest() {
324         final TypeDefinition<?> type = DerivedTypes.derivedTypeBuilder(BaseTypes.stringType(), ROOT_PATH).build();
325         final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(type);
326
327         assertNotNull(restrictions);
328         assertTrue(restrictions.isEmpty());
329     }
330
331     @Test
332     public void getDefaultIntegerRestrictionsTest() {
333         final TypeDefinition<?> type = DerivedTypes.derivedTypeBuilder(BaseTypes.int16Type(), ROOT_PATH).build();
334         final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(type);
335
336         assertNotNull(restrictions);
337         assertFalse(restrictions.isEmpty());
338         assertEquals(((Int16TypeDefinition) type.getBaseType()).getRangeConstraint(),
339                 restrictions.getRangeConstraint());
340         assertFalse(restrictions.getLengthConstraint().isPresent());
341         assertTrue(restrictions.getPatternConstraints().isEmpty());
342     }
343
344     @Test
345     public void getDefaultUnsignedIntegerRestrictionsTest() {
346         final TypeDefinition<?> type = DerivedTypes.derivedTypeBuilder(BaseTypes.uint16Type(), ROOT_PATH).build();
347         final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(type);
348
349         assertNotNull(restrictions);
350         assertFalse(restrictions.isEmpty());
351         assertEquals(((Uint16TypeDefinition) type.getBaseType()).getRangeConstraint(),
352                 restrictions.getRangeConstraint());
353         assertFalse(restrictions.getLengthConstraint().isPresent());
354         assertTrue(restrictions.getPatternConstraints().isEmpty());
355     }
356
357     @Test
358     public void getDefaultDecimalRestrictionsTest() {
359         final DecimalTypeDefinition base = BaseTypes.decimalTypeBuilder(ROOT_PATH).setFractionDigits(10).build();
360         final TypeDefinition<?> type = DerivedTypes.derivedTypeBuilder(base, ROOT_PATH).build();
361
362         final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(type);
363
364         assertNotNull(restrictions);
365         assertFalse(restrictions.isEmpty());
366         assertEquals(base.getRangeConstraint(), restrictions.getRangeConstraint());
367         assertFalse(restrictions.getLengthConstraint().isPresent());
368         assertTrue(restrictions.getPatternConstraints().isEmpty());
369     }
370
371     @Test
372     public void unicodeCharReplaceTest() {
373         String inputString = "abcu\\uuuuu\\uuua\\u\\\\uabc\\\\uuuu\\\\\\uuuu\\\\\\\\uuuu///uu/u/u/u/u/u/u";
374
375         assertEquals("abcu\\\\uuuuu\\\\uuua\\\\u\\\\uabc\\\\uuuu\\\\uuuu\\\\uuuu///uu/u/u/u/u/u/u",
376             BindingGeneratorUtil.replaceAllIllegalChars(inputString));
377     }
378 }