Binding DTOs: improve equals() implementation
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / test / java / org / opendaylight / mdsal / binding / java / api / generator / BuilderGeneratorTest.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.java.api.generator;
9
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;
14
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;
27
28 public class BuilderGeneratorTest {
29     private static final String TEST = "test";
30     private static final JavaTypeName TYPE_NAME = JavaTypeName.create(TEST, TEST);
31
32     @Test
33     public void basicTest() {
34         assertEquals("", new BuilderGenerator().generate(mock(Type.class)));
35     }
36
37     @Test
38     public void builderTemplateGenerateToStringWithPropertyTest() {
39         final GeneratedType genType = mockGenType("get" + TEST);
40
41         assertEquals("/**\n"
42                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
43                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
44                 + "\n * representations across all implementations.\n"
45                 + " *\n"
46                 + " * @param obj Object for which to generate toString() result.\n"
47                 + " * @return {@link String} value of data modeled by this interface.\n"
48                 + " * @throws NullPointerException if {@code obj} is null\n"
49                 + " */\n"
50                 + "static String bindingToString(final test.test obj) {\n"
51                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
52                 + "    CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
53                 + "    return helper.toString();\n"
54                 + "}\n", genToString(genType).toString());
55     }
56
57     @Test
58     public void builderTemplateGenerateToStringWithoutAnyPropertyTest() throws Exception {
59         assertEquals("/**\n"
60                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
61                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
62                 + "\n * representations across all implementations.\n"
63                 + " *\n"
64                 + " * @param obj Object for which to generate toString() result.\n"
65                 + " * @return {@link String} value of data modeled by this interface.\n"
66                 + " * @throws NullPointerException if {@code obj} is null\n"
67                 + " */\n"
68                 + "static String bindingToString(final test.test obj) {\n"
69                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
70                 + "    return helper.toString();\n"
71                 + "}\n", genToString(mockGenType(TEST)).toString());
72     }
73
74     @Test
75     public void builderTemplateGenerateToStringWithMorePropertiesTest() throws Exception {
76         assertEquals("/**\n"
77                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
78                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
79                 + "\n * representations across all implementations.\n"
80                 + " *\n"
81                 + " * @param obj Object for which to generate toString() result.\n"
82                 + " * @return {@link String} value of data modeled by this interface.\n"
83                 + " * @throws NullPointerException if {@code obj} is null\n"
84                 + " */\n"
85                 + "static String bindingToString(final test.test obj) {\n"
86                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
87                 + "    CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
88                 + "    CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
89                 + "    return helper.toString();\n"
90                 + "}\n", genToString(mockGenTypeMoreMeth("get" + TEST)).toString());
91     }
92
93     @Test
94     public void builderTemplateGenerateToStringWithoutPropertyWithAugmentTest() throws Exception {
95         assertEquals("/**\n"
96                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
97                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
98                 + "\n * representations across all implementations.\n"
99                 + " *\n"
100                 + " * @param <T$$> implementation type, which has to also implement AugmentationHolder interface\n"
101                 + " *              contract.\n"
102                 + " * @param obj Object for which to generate toString() result.\n"
103                 + " * @return {@link String} value of data modeled by this interface.\n"
104                 + " * @throws NullPointerException if {@code obj} is null\n"
105                 + " */\n"
106                 + "static <T$$ extends test.test & AugmentationHolder<test.test>> String bindingToString(final @NonNull"
107                 + " T$$ obj) {\n"
108                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
109                 + "    CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
110                 + "    return helper.toString();\n"
111                 + "}\n", genToString(mockAugment(mockGenType(TEST))).toString());
112     }
113
114     @Test
115     public void builderTemplateGenerateToStringWithPropertyWithAugmentTest() throws Exception {
116         assertEquals("/**\n"
117                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
118                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
119                 + "\n * representations across all implementations.\n"
120                 + " *\n"
121                 + " * @param <T$$> implementation type, which has to also implement AugmentationHolder interface\n"
122                 + " *              contract.\n"
123                 + " * @param obj Object for which to generate toString() result.\n"
124                 + " * @return {@link String} value of data modeled by this interface.\n"
125                 + " * @throws NullPointerException if {@code obj} is null\n"
126                 + " */\n"
127                 + "static <T$$ extends test.test & AugmentationHolder<test.test>> String bindingToString(final @NonNull"
128                 + " T$$ obj) {\n"
129                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
130                 + "    CodeHelpers.appendValue(helper, \"test\", obj.gettest());\n"
131                 + "    CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
132                 + "    return helper.toString();\n"
133                 + "}\n", genToString(mockAugment(mockGenType("get" + TEST))).toString());
134     }
135
136     @Test
137     public void builderTemplateGenerateToStringWithMorePropertiesWithAugmentTest() throws Exception {
138         assertEquals("/**\n"
139                 + " * Default implementation of {@link Object#toString()} contract for this interface.\n"
140                 + " * Implementations of this interface are encouraged to defer to this method to get consistent string"
141                 + "\n * representations across all implementations.\n"
142                 + " *\n"
143                 + " * @param <T$$> implementation type, which has to also implement AugmentationHolder interface\n"
144                 + " *              contract.\n"
145                 + " * @param obj Object for which to generate toString() result.\n"
146                 + " * @return {@link String} value of data modeled by this interface.\n"
147                 + " * @throws NullPointerException if {@code obj} is null\n"
148                 + " */\n"
149                 + "static <T$$ extends test.test & AugmentationHolder<test.test>> String bindingToString(final @NonNull"
150                 + " T$$ obj) {\n"
151                 + "    final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(\"test\");\n"
152                 + "    CodeHelpers.appendValue(helper, \"test1\", obj.gettest1());\n"
153                 + "    CodeHelpers.appendValue(helper, \"test2\", obj.gettest2());\n"
154                 + "    CodeHelpers.appendValue(helper, \"augmentation\", obj.augmentations().values());\n"
155                 + "    return helper.toString();\n"
156                 + "}\n", genToString(mockAugment(mockGenTypeMoreMeth("get" + TEST))).toString());
157     }
158
159     @Test
160     public void builderTemplateGenerateToEqualsComparingOrderTest() {
161         final EffectiveModelContext context = YangParserTestUtils.parseYangResource(
162                 "/test-types.yang");
163         final List<Type> types = new DefaultBindingGenerator().generateTypes(context);
164         final BuilderTemplate bt = BuilderGenerator.templateForType((GeneratedType) types.get(19));
165
166         final List<String> sortedProperties = bt.properties.stream()
167                 .sorted(ByTypeMemberComparator.getInstance())
168                 .map(BuilderGeneratedProperty::getName)
169                 .collect(Collectors.toList());
170
171         assertEquals(List.of(
172                 // numeric types (boolean, byte, short, int, long, biginteger, bigdecimal), identityrefs, empty
173                 "id16", "id16Def", "id32", "id32Def", "id64", "id64Def", "id8", "id8Def", "idBoolean", "idBooleanDef",
174                 "idDecimal64", "idDecimal64Def","idEmpty", "idEmptyDef", "idIdentityref", "idIdentityrefDef",
175                 "idLeafref", "idLeafrefDef", "idU16", "idU16Def", "idU32", "idU32Def", "idU64", "idU64Def", "idU8",
176                 "idU8Def",
177                 // string, binary, bits
178                 "idBinary", "idBinaryDef", "idBits", "idBitsDef", "idGroupLeafString", "idLeafrefContainer1",
179                 "idLeafrefContainer1Def", "idString", "idStringDef",
180                 // instance identifier
181                 "idInstanceIdentifier", "idInstanceIdentifierDef",
182                 // other types
183                 "idContainer1", "idContainer2", "idEnumeration", "idEnumerationDef",
184                 "idGroupContainer", "idList", "idUnion", "idUnionDef"), sortedProperties);
185     }
186
187     private static GeneratedType mockAugment(final GeneratedType genType) {
188         final List<Type> impls = new ArrayList<>();
189         final Type impl = mock(Type.class);
190         doReturn("org.opendaylight.yangtools.yang.binding.Augmentable").when(impl).getFullyQualifiedName();
191         impls.add(impl);
192         doReturn(impls).when(genType).getImplements();
193         return genType;
194     }
195
196     private static GeneratedType mockGenTypeMoreMeth(final String methodeName) {
197         final GeneratedType genType = spy(GeneratedType.class);
198         doReturn(TYPE_NAME).when(genType).getIdentifier();
199         doReturn(TEST).when(genType).getName();
200         doReturn(TEST).when(genType).getPackageName();
201
202         final List<MethodSignature> listMethodSign = new ArrayList<>();
203         for (int i = 0; i < 2; i++) {
204             final MethodSignature methSign = mockMethSign(methodeName + (i + 1));
205             listMethodSign.add(methSign);
206         }
207         doReturn(listMethodSign).when(genType).getMethodDefinitions();
208
209         final List<Type> impls = new ArrayList<>();
210         doReturn(impls).when(genType).getImplements();
211         return genType;
212     }
213
214     private static CharSequence genToString(final GeneratedType genType) {
215         return new InterfaceTemplate(genType).generateBindingToString();
216     }
217
218     private static GeneratedType mockGenType(final String methodeName) {
219         final GeneratedType genType = spy(GeneratedType.class);
220         doReturn(TYPE_NAME).when(genType).getIdentifier();
221         doReturn(TEST).when(genType).getName();
222         doReturn(TEST).when(genType).getPackageName();
223
224         final List<MethodSignature> listMethodSign = new ArrayList<>();
225         final MethodSignature methSign = mockMethSign(methodeName);
226         listMethodSign.add(methSign);
227         doReturn(listMethodSign).when(genType).getMethodDefinitions();
228
229         final List<Type> impls = new ArrayList<>();
230         doReturn(impls).when(genType).getImplements();
231         return genType;
232     }
233
234     private static MethodSignature mockMethSign(final String methodeName) {
235         final MethodSignature methSign = mock(MethodSignature.class);
236         doReturn(methodeName).when(methSign).getName();
237         final Type methType = mock(Type.class);
238         doReturn(TYPE_NAME).when(methType).getIdentifier();
239         doReturn(methType).when(methSign).getReturnType();
240         doReturn(ValueMechanics.NORMAL).when(methSign).getMechanics();
241         return methSign;
242     }
243 }