2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.binding.java.api.generator;
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Mockito.doCallRealMethod;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.spy;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.stream.Collectors;
19 import org.junit.Test;
20 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingGenerator;
21 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
22 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
23 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
24 import org.opendaylight.mdsal.binding.model.api.MethodSignature.ValueMechanics;
25 import org.opendaylight.mdsal.binding.model.api.Type;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
29 public class BuilderGeneratorTest {
30 private static final String TEST = "test";
31 private static final JavaTypeName TYPE_NAME = JavaTypeName.create(TEST, TEST);
34 public void basicTest() {
35 assertEquals("", new BuilderGenerator().generate(mock(Type.class)));
39 public void builderTemplateGenerateHashcodeWithPropertyTest() {
40 final GeneratedType genType = mockGenType("get" + TEST);
43 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
44 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
46 + " * results across all implementations.\n"
48 + " * @param obj Object for which to generate hashCode() result.\n"
49 + " * @return Hash code value of data modeled by this interface.\n"
50 + " * @throws NullPointerException if {@code obj} is null\n"
52 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
53 + " final int prime = 31;\n"
54 + " int result = 1;\n"
55 + " result = prime * result + Objects.hashCode(obj.getTest());\n"
57 + "}\n", genHashCode(genType).toString());
61 public void builderTemplateGenerateHashCodeWithoutAnyPropertyTest() throws Exception {
62 assertEquals("", genHashCode(mockGenType(TEST)).toString());
66 public void builderTemplateGenerateHashCodeWithMorePropertiesTest() throws Exception {
68 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
69 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
71 + " * results across all implementations.\n"
73 + " * @param obj Object for which to generate hashCode() result.\n"
74 + " * @return Hash code value of data modeled by this interface.\n"
75 + " * @throws NullPointerException if {@code obj} is null\n"
77 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
78 + " final int prime = 31;\n"
79 + " int result = 1;\n"
80 + " result = prime * result + Objects.hashCode(obj.getTest1());\n"
81 + " result = prime * result + Objects.hashCode(obj.getTest2());\n"
83 + "}\n", genHashCode(mockGenTypeMoreMeth("get" + TEST)).toString());
87 public void builderTemplateGenerateHashCodeWithoutPropertyWithAugmentTest() throws Exception {
89 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
90 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
92 + " * results across all implementations.\n"
94 + " * @param obj Object for which to generate hashCode() result.\n"
95 + " * @return Hash code value of data modeled by this interface.\n"
96 + " * @throws NullPointerException if {@code obj} is null\n"
98 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
99 + " final int prime = 31;\n"
100 + " int result = 1;\n"
101 + " result = prime * result + obj.augmentations().hashCode();\n"
102 + " return result;\n"
103 + "}\n", genHashCode(mockAugment(mockGenType(TEST))).toString());
107 public void builderTemplateGenerateHashCodeWithPropertyWithAugmentTest() throws Exception {
109 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
110 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
112 + " * results across all implementations.\n"
114 + " * @param obj Object for which to generate hashCode() result.\n"
115 + " * @return Hash code value of data modeled by this interface.\n"
116 + " * @throws NullPointerException if {@code obj} is null\n"
118 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
119 + " final int prime = 31;\n"
120 + " int result = 1;\n"
121 + " result = prime * result + Objects.hashCode(obj.getTest());\n"
122 + " result = prime * result + obj.augmentations().hashCode();\n"
123 + " return result;\n"
124 + "}\n", genHashCode(mockAugment(mockGenType("get" + TEST))).toString());
128 public void builderTemplateGenerateHashCodeWithMorePropertiesWithAugmentTest() throws Exception {
130 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
131 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
133 + " * results across all implementations.\n"
135 + " * @param obj Object for which to generate hashCode() result.\n"
136 + " * @return Hash code value of data modeled by this interface.\n"
137 + " * @throws NullPointerException if {@code obj} is null\n"
139 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
140 + " final int prime = 31;\n"
141 + " int result = 1;\n"
142 + " result = prime * result + Objects.hashCode(obj.getTest1());\n"
143 + " result = prime * result + Objects.hashCode(obj.getTest2());\n"
144 + " result = prime * result + obj.augmentations().hashCode();\n"
145 + " return result;\n"
146 + "}\n", genHashCode(mockAugment(mockGenTypeMoreMeth("get" + TEST))).toString());
150 public void builderTemplateGenerateToStringWithPropertyTest() {
151 final GeneratedType genType = mockGenType("get" + TEST);
154 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
155 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
156 + "\n * representations across all implementations.\n"
158 + " * @param obj Object for which to generate toString() result.\n"
159 + " * @return {@link String} value of data modeled by this interface.\n"
160 + " * @throws NullPointerException if {@code obj} is null\n"
162 + "static String bindingToString(final test.@NonNull test obj) {\n"
163 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
164 + " CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
165 + " return helper.toString();\n"
166 + "}\n", genToString(genType).toString());
170 public void builderTemplateGenerateToStringWithoutAnyPropertyTest() throws Exception {
172 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
173 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
174 + "\n * representations across all implementations.\n"
176 + " * @param obj Object for which to generate toString() result.\n"
177 + " * @return {@link String} value of data modeled by this interface.\n"
178 + " * @throws NullPointerException if {@code obj} is null\n"
180 + "static String bindingToString(final test.@NonNull test obj) {\n"
181 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
182 + " return helper.toString();\n"
183 + "}\n", genToString(mockGenType(TEST)).toString());
187 public void builderTemplateGenerateToStringWithMorePropertiesTest() throws Exception {
189 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
190 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
191 + "\n * representations across all implementations.\n"
193 + " * @param obj Object for which to generate toString() result.\n"
194 + " * @return {@link String} value of data modeled by this interface.\n"
195 + " * @throws NullPointerException if {@code obj} is null\n"
197 + "static String bindingToString(final test.@NonNull test obj) {\n"
198 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
199 + " CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
200 + " CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
201 + " return helper.toString();\n"
202 + "}\n", genToString(mockGenTypeMoreMeth("get" + TEST)).toString());
206 public void builderTemplateGenerateToStringWithoutPropertyWithAugmentTest() throws Exception {
208 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
209 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
210 + "\n * representations across all implementations.\n"
212 + " * @param obj Object for which to generate toString() result.\n"
213 + " * @return {@link String} value of data modeled by this interface.\n"
214 + " * @throws NullPointerException if {@code obj} is null\n"
216 + "static String bindingToString(final test.@NonNull test obj) {\n"
217 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
218 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
219 + " return helper.toString();\n"
220 + "}\n", genToString(mockAugment(mockGenType(TEST))).toString());
224 public void builderTemplateGenerateToStringWithPropertyWithAugmentTest() throws Exception {
226 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
227 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
228 + "\n * representations across all implementations.\n"
230 + " * @param obj Object for which to generate toString() result.\n"
231 + " * @return {@link String} value of data modeled by this interface.\n"
232 + " * @throws NullPointerException if {@code obj} is null\n"
234 + "static String bindingToString(final test.@NonNull test obj) {\n"
235 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
236 + " CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
237 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
238 + " return helper.toString();\n"
239 + "}\n", genToString(mockAugment(mockGenType("get" + TEST))).toString());
243 public void builderTemplateGenerateToStringWithMorePropertiesWithAugmentTest() throws Exception {
245 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
246 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
247 + "\n * representations across all implementations.\n"
249 + " * @param obj Object for which to generate toString() result.\n"
250 + " * @return {@link String} value of data modeled by this interface.\n"
251 + " * @throws NullPointerException if {@code obj} is null\n"
253 + "static String bindingToString(final test.@NonNull test obj) {\n"
254 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
255 + " CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
256 + " CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
257 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
258 + " return helper.toString();\n"
259 + "}\n", genToString(mockAugment(mockGenTypeMoreMeth("get" + TEST))).toString());
263 public void builderTemplateGenerateToEqualsComparingOrderTest() {
264 final EffectiveModelContext context = YangParserTestUtils.parseYangResource(
266 final List<GeneratedType> types = new DefaultBindingGenerator().generateTypes(context);
267 final BuilderTemplate bt = BuilderGenerator.templateForType(types.get(19));
269 final List<String> sortedProperties = bt.properties.stream()
270 .sorted(ByTypeMemberComparator.getInstance())
271 .map(BuilderGeneratedProperty::getName)
272 .collect(Collectors.toList());
274 assertEquals(List.of(
275 // numeric types (boolean, byte, short, int, long, biginteger, bigdecimal), identityrefs, empty
276 "id16", "id16Def", "id32", "id32Def", "id64", "id64Def", "id8", "id8Def", "idBoolean", "idBooleanDef",
277 "idDecimal64", "idDecimal64Def","idEmpty", "idEmptyDef", "idIdentityref", "idIdentityrefDef",
278 "idLeafref", "idLeafrefDef", "idU16", "idU16Def", "idU32", "idU32Def", "idU64", "idU64Def", "idU8",
280 // string, binary, bits
281 "idBinary", "idBinaryDef", "idBits", "idBitsDef", "idGroupLeafString", "idLeafrefContainer1",
282 "idLeafrefContainer1Def", "idString", "idStringDef",
283 // instance identifier
284 "idInstanceIdentifier", "idInstanceIdentifierDef",
286 "idContainer1", "idContainer2", "idEnumeration", "idEnumerationDef",
287 "idGroupContainer", "idList", "idUnion", "idUnionDef"), sortedProperties);
290 private static GeneratedType mockAugment(final GeneratedType genType) {
291 final List<Type> impls = new ArrayList<>();
292 final Type impl = mock(Type.class);
293 doReturn("org.opendaylight.yangtools.yang.binding.Augmentable").when(impl).getFullyQualifiedName();
295 doReturn(impls).when(genType).getImplements();
299 private static GeneratedType mockGenTypeMoreMeth(final String methodeName) {
300 final GeneratedType genType = spy(GeneratedType.class);
301 doReturn(TYPE_NAME).when(genType).getIdentifier();
302 doReturn(TEST).when(genType).getName();
303 doReturn(TEST).when(genType).getPackageName();
305 final List<MethodSignature> listMethodSign = new ArrayList<>();
306 for (int i = 0; i < 2; i++) {
307 final MethodSignature methSign = mockMethSign(methodeName + (i + 1));
308 listMethodSign.add(methSign);
310 doReturn(listMethodSign).when(genType).getMethodDefinitions();
312 final List<Type> impls = new ArrayList<>();
313 doReturn(impls).when(genType).getImplements();
317 private static CharSequence genToString(final GeneratedType genType) {
318 return new InterfaceTemplate(genType).generateBindingToString();
321 private static CharSequence genHashCode(final GeneratedType genType) {
322 return new InterfaceTemplate(genType).generateBindingHashCode();
325 private static GeneratedType mockGenType(final String methodeName) {
326 final GeneratedType genType = spy(GeneratedType.class);
327 doReturn(TYPE_NAME).when(genType).getIdentifier();
328 doReturn(TEST).when(genType).getName();
329 doReturn(TEST).when(genType).getPackageName();
331 final List<MethodSignature> listMethodSign = new ArrayList<>();
332 final MethodSignature methSign = mockMethSign(methodeName);
333 listMethodSign.add(methSign);
334 doReturn(listMethodSign).when(genType).getMethodDefinitions();
336 final List<Type> impls = new ArrayList<>();
337 doReturn(impls).when(genType).getImplements();
341 private static MethodSignature mockMethSign(final String methodeName) {
342 final MethodSignature methSign = mock(MethodSignature.class);
343 doReturn(methodeName).when(methSign).getName();
344 final Type methType = mock(Type.class);
345 doCallRealMethod().when(methType).getFullyQualifiedName();
346 doReturn(TYPE_NAME).when(methType).getIdentifier();
347 doReturn(TEST).when(methType).getName();
348 doReturn(methType).when(methSign).getReturnType();
349 doReturn(ValueMechanics.NORMAL).when(methSign).getMechanics();