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.doReturn;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.spy;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.stream.Collectors;
18 import org.junit.Test;
19 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingGenerator;
20 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
21 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
22 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
23 import org.opendaylight.mdsal.binding.model.api.MethodSignature.ValueMechanics;
24 import org.opendaylight.mdsal.binding.model.api.Type;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
28 public class BuilderGeneratorTest {
29 private static final String TEST = "test";
30 private static final JavaTypeName TYPE_NAME = JavaTypeName.create(TEST, TEST);
33 public void basicTest() {
34 assertEquals("", new BuilderGenerator().generate(mock(Type.class)));
38 public void builderTemplateGenerateHashcodeWithPropertyTest() {
39 final GeneratedType genType = mockGenType("get" + TEST);
42 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
43 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
45 + " * results across all implementations.\n"
47 + " * @param obj Object for which to generate hashCode() result.\n"
48 + " * @return Hash code value of data modeled by this interface.\n"
49 + " * @throws NullPointerException if {@code obj} is null\n"
51 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
52 + " final int prime = 31;\n"
53 + " int result = 1;\n"
54 + " result = prime * result + Objects.hashCode(obj.getTest());\n"
56 + "}\n", genHashCode(genType).toString());
60 public void builderTemplateGenerateHashCodeWithoutAnyPropertyTest() throws Exception {
61 assertEquals("", genHashCode(mockGenType(TEST)).toString());
65 public void builderTemplateGenerateHashCodeWithMorePropertiesTest() throws Exception {
67 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
68 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
70 + " * results across all implementations.\n"
72 + " * @param obj Object for which to generate hashCode() result.\n"
73 + " * @return Hash code value of data modeled by this interface.\n"
74 + " * @throws NullPointerException if {@code obj} is null\n"
76 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
77 + " final int prime = 31;\n"
78 + " int result = 1;\n"
79 + " result = prime * result + Objects.hashCode(obj.getTest1());\n"
80 + " result = prime * result + Objects.hashCode(obj.getTest2());\n"
82 + "}\n", genHashCode(mockGenTypeMoreMeth("get" + TEST)).toString());
86 public void builderTemplateGenerateHashCodeWithoutPropertyWithAugmentTest() throws Exception {
88 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
89 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
91 + " * results across all implementations.\n"
93 + " * @param obj Object for which to generate hashCode() result.\n"
94 + " * @return Hash code value of data modeled by this interface.\n"
95 + " * @throws NullPointerException if {@code obj} is null\n"
97 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
98 + " final int prime = 31;\n"
99 + " int result = 1;\n"
100 + " result = prime * result + obj.augmentations().hashCode();\n"
101 + " return result;\n"
102 + "}\n", genHashCode(mockAugment(mockGenType(TEST))).toString());
106 public void builderTemplateGenerateHashCodeWithPropertyWithAugmentTest() throws Exception {
108 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
109 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
111 + " * results across all implementations.\n"
113 + " * @param obj Object for which to generate hashCode() result.\n"
114 + " * @return Hash code value of data modeled by this interface.\n"
115 + " * @throws NullPointerException if {@code obj} is null\n"
117 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
118 + " final int prime = 31;\n"
119 + " int result = 1;\n"
120 + " result = prime * result + Objects.hashCode(obj.getTest());\n"
121 + " result = prime * result + obj.augmentations().hashCode();\n"
122 + " return result;\n"
123 + "}\n", genHashCode(mockAugment(mockGenType("get" + TEST))).toString());
127 public void builderTemplateGenerateHashCodeWithMorePropertiesWithAugmentTest() throws Exception {
129 + " * Default implementation of {@link Object#hashCode()} contract for this interface.\n"
130 + " * Implementations of this interface are encouraged to defer to this method to get consistent"
132 + " * results across all implementations.\n"
134 + " * @param obj Object for which to generate hashCode() result.\n"
135 + " * @return Hash code value of data modeled by this interface.\n"
136 + " * @throws NullPointerException if {@code obj} is null\n"
138 + "static int bindingHashCode(final test.@NonNull test obj) {\n"
139 + " final int prime = 31;\n"
140 + " int result = 1;\n"
141 + " result = prime * result + Objects.hashCode(obj.getTest1());\n"
142 + " result = prime * result + Objects.hashCode(obj.getTest2());\n"
143 + " result = prime * result + obj.augmentations().hashCode();\n"
144 + " return result;\n"
145 + "}\n", genHashCode(mockAugment(mockGenTypeMoreMeth("get" + TEST))).toString());
149 public void builderTemplateGenerateToStringWithPropertyTest() {
150 final GeneratedType genType = mockGenType("get" + TEST);
153 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
154 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
155 + "\n * representations across all implementations.\n"
157 + " * @param obj Object for which to generate toString() result.\n"
158 + " * @return {@link String} value of data modeled by this interface.\n"
159 + " * @throws NullPointerException if {@code obj} is null\n"
161 + "static String bindingToString(final test.@NonNull test obj) {\n"
162 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
163 + " CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
164 + " return helper.toString();\n"
165 + "}\n", genToString(genType).toString());
169 public void builderTemplateGenerateToStringWithoutAnyPropertyTest() throws Exception {
171 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
172 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
173 + "\n * representations across all implementations.\n"
175 + " * @param obj Object for which to generate toString() result.\n"
176 + " * @return {@link String} value of data modeled by this interface.\n"
177 + " * @throws NullPointerException if {@code obj} is null\n"
179 + "static String bindingToString(final test.@NonNull test obj) {\n"
180 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
181 + " return helper.toString();\n"
182 + "}\n", genToString(mockGenType(TEST)).toString());
186 public void builderTemplateGenerateToStringWithMorePropertiesTest() throws Exception {
188 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
189 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
190 + "\n * representations across all implementations.\n"
192 + " * @param obj Object for which to generate toString() result.\n"
193 + " * @return {@link String} value of data modeled by this interface.\n"
194 + " * @throws NullPointerException if {@code obj} is null\n"
196 + "static String bindingToString(final test.@NonNull test obj) {\n"
197 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
198 + " CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
199 + " CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
200 + " return helper.toString();\n"
201 + "}\n", genToString(mockGenTypeMoreMeth("get" + TEST)).toString());
205 public void builderTemplateGenerateToStringWithoutPropertyWithAugmentTest() throws Exception {
207 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
208 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
209 + "\n * representations across all implementations.\n"
211 + " * @param obj Object for which to generate toString() result.\n"
212 + " * @return {@link String} value of data modeled by this interface.\n"
213 + " * @throws NullPointerException if {@code obj} is null\n"
215 + "static String bindingToString(final test.@NonNull test obj) {\n"
216 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
217 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
218 + " return helper.toString();\n"
219 + "}\n", genToString(mockAugment(mockGenType(TEST))).toString());
223 public void builderTemplateGenerateToStringWithPropertyWithAugmentTest() throws Exception {
225 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
226 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
227 + "\n * representations across all implementations.\n"
229 + " * @param obj Object for which to generate toString() result.\n"
230 + " * @return {@link String} value of data modeled by this interface.\n"
231 + " * @throws NullPointerException if {@code obj} is null\n"
233 + "static String bindingToString(final test.@NonNull test obj) {\n"
234 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
235 + " CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
236 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
237 + " return helper.toString();\n"
238 + "}\n", genToString(mockAugment(mockGenType("get" + TEST))).toString());
242 public void builderTemplateGenerateToStringWithMorePropertiesWithAugmentTest() throws Exception {
244 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
245 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
246 + "\n * representations across all implementations.\n"
248 + " * @param obj Object for which to generate toString() result.\n"
249 + " * @return {@link String} value of data modeled by this interface.\n"
250 + " * @throws NullPointerException if {@code obj} is null\n"
252 + "static String bindingToString(final test.@NonNull test obj) {\n"
253 + " final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
254 + " CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
255 + " CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
256 + " CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
257 + " return helper.toString();\n"
258 + "}\n", genToString(mockAugment(mockGenTypeMoreMeth("get" + TEST))).toString());
262 public void builderTemplateGenerateToEqualsComparingOrderTest() {
263 final EffectiveModelContext context = YangParserTestUtils.parseYangResource(
265 final List<Type> types = new DefaultBindingGenerator().generateTypes(context);
266 final BuilderTemplate bt = BuilderGenerator.templateForType((GeneratedType) types.get(19));
268 final List<String> sortedProperties = bt.properties.stream()
269 .sorted(ByTypeMemberComparator.getInstance())
270 .map(BuilderGeneratedProperty::getName)
271 .collect(Collectors.toList());
273 assertEquals(List.of(
274 // numeric types (boolean, byte, short, int, long, biginteger, bigdecimal), identityrefs, empty
275 "id16", "id16Def", "id32", "id32Def", "id64", "id64Def", "id8", "id8Def", "idBoolean", "idBooleanDef",
276 "idDecimal64", "idDecimal64Def","idEmpty", "idEmptyDef", "idIdentityref", "idIdentityrefDef",
277 "idLeafref", "idLeafrefDef", "idU16", "idU16Def", "idU32", "idU32Def", "idU64", "idU64Def", "idU8",
279 // string, binary, bits
280 "idBinary", "idBinaryDef", "idBits", "idBitsDef", "idGroupLeafString", "idLeafrefContainer1",
281 "idLeafrefContainer1Def", "idString", "idStringDef",
282 // instance identifier
283 "idInstanceIdentifier", "idInstanceIdentifierDef",
285 "idContainer1", "idContainer2", "idEnumeration", "idEnumerationDef",
286 "idGroupContainer", "idList", "idUnion", "idUnionDef"), sortedProperties);
289 private static GeneratedType mockAugment(final GeneratedType genType) {
290 final List<Type> impls = new ArrayList<>();
291 final Type impl = mock(Type.class);
292 doReturn("org.opendaylight.yangtools.yang.binding.Augmentable").when(impl).getFullyQualifiedName();
294 doReturn(impls).when(genType).getImplements();
298 private static GeneratedType mockGenTypeMoreMeth(final String methodeName) {
299 final GeneratedType genType = spy(GeneratedType.class);
300 doReturn(TYPE_NAME).when(genType).getIdentifier();
301 doReturn(TEST).when(genType).getName();
302 doReturn(TEST).when(genType).getPackageName();
304 final List<MethodSignature> listMethodSign = new ArrayList<>();
305 for (int i = 0; i < 2; i++) {
306 final MethodSignature methSign = mockMethSign(methodeName + (i + 1));
307 listMethodSign.add(methSign);
309 doReturn(listMethodSign).when(genType).getMethodDefinitions();
311 final List<Type> impls = new ArrayList<>();
312 doReturn(impls).when(genType).getImplements();
316 private static CharSequence genToString(final GeneratedType genType) {
317 return new InterfaceTemplate(genType).generateBindingToString();
320 private static CharSequence genHashCode(final GeneratedType genType) {
321 return new InterfaceTemplate(genType).generateBindingHashCode();
324 private static GeneratedType mockGenType(final String methodeName) {
325 final GeneratedType genType = spy(GeneratedType.class);
326 doReturn(TYPE_NAME).when(genType).getIdentifier();
327 doReturn(TEST).when(genType).getName();
328 doReturn(TEST).when(genType).getPackageName();
330 final List<MethodSignature> listMethodSign = new ArrayList<>();
331 final MethodSignature methSign = mockMethSign(methodeName);
332 listMethodSign.add(methSign);
333 doReturn(listMethodSign).when(genType).getMethodDefinitions();
335 final List<Type> impls = new ArrayList<>();
336 doReturn(impls).when(genType).getImplements();
340 private static MethodSignature mockMethSign(final String methodeName) {
341 final MethodSignature methSign = mock(MethodSignature.class);
342 doReturn(methodeName).when(methSign).getName();
343 final Type methType = mock(Type.class);
344 doReturn(TYPE_NAME).when(methType).getIdentifier();
345 doReturn(TEST).when(methType).getName();
346 doReturn(methType).when(methSign).getReturnType();
347 doReturn(ValueMechanics.NORMAL).when(methSign).getMechanics();