Do not generate union builders
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / test / java / org / opendaylight / mdsal / binding / java / api / generator / SpecializingLeafrefTest.java
1 /*
2  * Copyright (c) 2020 Pantheon Technologies, s.r.o.  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.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.CoreMatchers.not;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertNotNull;
15 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.DOUBLE_TAB;
16 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.TAB;
17 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.TRIPLE_TAB;
18 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.doubleTab;
19 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.getFiles;
20 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.tab;
21 import static org.opendaylight.mdsal.binding.java.api.generator.FileSearchUtil.tripleTab;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.URISyntaxException;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.util.List;
29 import java.util.Map;
30 import org.junit.After;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
34 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
35 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
36 import org.opendaylight.mdsal.binding.model.api.Type;
37 import org.opendaylight.mdsal.binding.model.ri.Types;
38 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
39
40 public class SpecializingLeafrefTest extends BaseCompilationTest {
41     private static final ParameterizedType SET_STRING_TYPE  = Types.setTypeFor(Types.STRING);
42
43     public static final String BAR_CONT = "BarCont";
44     public static final String BOOLEAN_CONT = "BooleanCont";
45
46     private static final String BAR_LST = "BarLst";
47     private static final String BAZ_GRP = "BazGrp";
48     private static final String FOO_GRP = "FooGrp";
49     private static final String RESOLVED_LEAF_GRP = "ResolvedLeafGrp";
50     private static final String RESOLVED_LEAFLIST_GRP = "ResolvedLeafListGrp";
51     private static final String TRANSITIVE_GROUP = "TransitiveGroup";
52     private static final String UNRESOLVED_GROUPING = "UnresolvedGrouping";
53
54     private static final String GET_LEAF1_NAME = "getLeaf1";
55     private static final String GET_LEAFLIST1_NAME = "getLeafList1";
56
57     private static final String GET_LEAF1_TYPE_OBJECT = "    Object getLeaf1();";
58     private static final String GET_LEAF1_TYPE_STRING = "    String getLeaf1();";
59     private static final String GET_LEAFLIST1_WILDCARD = "    @Nullable Set<?> getLeafList1();";
60     private static final String GET_LEAFLIST1_STRING = "    @Nullable Set<String> getLeafList1();";
61     private static final String GET_LEAFLIST1_DECLARATION = " getLeafList1();";
62     private static final String GET_LEAF1_DECLARATION = " getLeaf1();";
63
64     private static final char CLOSING_METHOD_BRACE = '}';
65     private static final String TAB_CLOSING_METHOD_BRACE = TAB + CLOSING_METHOD_BRACE;
66     private static final String DTAB_CLOSING_METHOD_BRACE = DOUBLE_TAB + CLOSING_METHOD_BRACE;
67
68     private static final String FOO_GRP_REF = "FooGrp";
69     private static final String RESOLVED_LEAF_GRP_REF = "ResolvedLeafGrp";
70
71     private static final String UNRESOLVED_GROUPING_REF =
72             "UnresolvedGrouping";
73
74     private static final String ARG_AS_FOO_GRP = "((" + FOO_GRP_REF + ")arg)";
75
76     private static final String LEAF2_ASSIGNMENT = "this._leaf2 = arg.getLeaf2();";
77
78     private static final String TAB_FIELDS_FROM_SIGNATURE = TAB + "public void fieldsFrom(DataObject arg) {";
79     private static final String TTAB_SET_IS_VALID_ARG_TRUE = TRIPLE_TAB + "isValidArg = true;";
80     private static final String DTAB_INIT_IS_VALID_ARG_FALSE = DOUBLE_TAB + "boolean isValidArg = false;";
81
82     private File sourcesOutputDir;
83     private File compiledOutputDir;
84     private List<GeneratedType> types;
85     private Map<String, File> files;
86
87     @Before
88     public void before() throws IOException, URISyntaxException {
89         sourcesOutputDir = CompilationTestUtils.generatorOutput("mdsal426");
90         compiledOutputDir = CompilationTestUtils.compilerOutput("mdsal426");
91         types = generateTestSources("/compilation/mdsal426", sourcesOutputDir);
92         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
93         files = getFiles(sourcesOutputDir);
94     }
95
96     @After
97     public void after() {
98         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
99     }
100
101     @Test
102     public void testGroupingWithUnresolvedLeafRefs() throws IOException {
103         verifyReturnType(FOO_GRP, GET_LEAF1_NAME, Types.objectType());
104         verifyReturnType(FOO_GRP, GET_LEAFLIST1_NAME, Types.setTypeWildcard());
105
106         final String content = getFileContent(FOO_GRP);
107
108         assertThat(content, containsString(GET_LEAF1_TYPE_OBJECT));
109         assertThat(content, containsString(GET_LEAFLIST1_WILDCARD));
110     }
111
112     @Test
113     public void testLeafLeafrefPointsLeaf() throws IOException {
114         verifyReturnType(RESOLVED_LEAF_GRP, GET_LEAF1_NAME, Types.STRING);
115
116         final String content = getFileContent(RESOLVED_LEAF_GRP);
117
118         assertThat(content, containsString(GET_LEAF1_TYPE_STRING));
119     }
120
121     @Test
122     public void testLeafLeafrefPointsLeafList() throws IOException {
123         verifyReturnType(RESOLVED_LEAFLIST_GRP, GET_LEAF1_NAME, Types.STRING);
124
125         final String content = getFileContent(RESOLVED_LEAF_GRP);
126
127         assertThat(content, containsString(GET_LEAF1_TYPE_STRING));
128     }
129
130     @Test
131     public void testLeafListLeafrefPointsLeaf() throws IOException {
132         verifyReturnType(RESOLVED_LEAF_GRP, GET_LEAFLIST1_NAME, SET_STRING_TYPE);
133
134         final String content = getFileContent(RESOLVED_LEAF_GRP);
135
136         assertOverriddenGetter(content, GET_LEAFLIST1_STRING);
137     }
138
139     @Test
140     public void testLeafListLeafrefPointsLeafList() throws IOException {
141         verifyReturnType(RESOLVED_LEAFLIST_GRP, GET_LEAFLIST1_NAME, SET_STRING_TYPE);
142
143         final String content = getFileContent(RESOLVED_LEAFLIST_GRP);
144
145         assertOverriddenGetter(content, GET_LEAFLIST1_STRING);
146     }
147
148     @Test
149     public void testGroupingWhichInheritUnresolvedLeafrefAndDoesNotDefineIt() throws IOException {
150         verifyMethodAbsence(TRANSITIVE_GROUP, GET_LEAF1_NAME);
151         verifyMethodAbsence(TRANSITIVE_GROUP, GET_LEAFLIST1_NAME);
152
153         final String content = getFileContent(TRANSITIVE_GROUP);
154
155         assertThat(content, not(containsString(GET_LEAF1_DECLARATION)));
156         assertThat(content, not(containsString(GET_LEAFLIST1_DECLARATION)));
157     }
158
159     @Test
160     public void testLeafrefWhichPointsBoolean() throws IOException {
161         verifyReturnType(UNRESOLVED_GROUPING, GET_LEAF1_NAME, Types.objectType());
162         verifyReturnType(BOOLEAN_CONT, GET_LEAF1_NAME, Types.BOOLEAN);
163
164         final String unresolvedGrouping = getFileContent(UNRESOLVED_GROUPING);
165         final String booleanCont = getFileContent(BOOLEAN_CONT);
166
167         assertNotOverriddenGetter(unresolvedGrouping, GET_LEAF1_TYPE_OBJECT);
168         assertThat(booleanCont, containsString(GET_LEAF1_DECLARATION));
169     }
170
171     @Test
172     public void testGroupingsUsageWhereLeafrefAlreadyResolved() throws IOException {
173         leafList1AndLeaf1Absence(BAR_CONT);
174         leafList1AndLeaf1Absence(BAR_LST);
175         leafList1AndLeaf1Absence(BAZ_GRP);
176     }
177
178     private void leafList1AndLeaf1Absence(final String typeName) throws IOException {
179         verifyMethodAbsence(typeName, GET_LEAF1_NAME);
180         verifyMethodAbsence(typeName, GET_LEAFLIST1_NAME);
181
182         final String content = getFileContent(typeName);
183
184         assertThat(content, not(containsString(GET_LEAF1_DECLARATION)));
185         assertThat(content, not(containsString(GET_LEAFLIST1_DECLARATION)));
186     }
187
188     private static void assertNotOverriddenGetter(final String fileContent, final String getterString) {
189         assertThat(fileContent, not(containsString("@Override" + System.lineSeparator() + getterString)));
190         assertThat(fileContent, containsString(getterString));
191     }
192
193     private static void assertOverriddenGetter(final String fileContent, final String getterString) {
194         assertThat(fileContent, containsString("@Override" + System.lineSeparator() + getterString));
195     }
196
197     @Test
198     public void barContBuilderDataObjectTest() throws IOException {
199         final File file = files.get(getJavaBuilderFileName(BAR_CONT));
200         final String content = Files.readString(file.toPath());
201
202         barContBuilderConstructorResolvedLeafGrpTest(file, content);
203         barContBuilderConstructorFooGrpTest(file, content);
204         barContBuilderFieldsFromTest(file, content);
205     }
206
207     private static void barContBuilderConstructorResolvedLeafGrpTest(final File file, final String content) {
208         FileSearchUtil.assertFileContainsConsecutiveLines(file, content,
209                 tab("public BarContBuilder(" + RESOLVED_LEAF_GRP_REF + " arg) {"),
210                 doubleTab("this._leaf1 = arg.getLeaf1();"),
211                 doubleTab("this._leafList1 = arg.getLeafList1();"),
212                 doubleTab("this._name = arg.getName();"),
213                 doubleTab(LEAF2_ASSIGNMENT),
214                 TAB_CLOSING_METHOD_BRACE);
215     }
216
217     private static void barContBuilderFieldsFromTest(final File file, final String content) {
218         FileSearchUtil.assertFileContainsConsecutiveLines(file, content,
219                 TAB_FIELDS_FROM_SIGNATURE,
220                 DTAB_INIT_IS_VALID_ARG_FALSE,
221                 doubleTab("if (arg instanceof " + FOO_GRP_REF + ") {"),
222                 tripleTab("this._leaf1 = CodeHelpers.checkFieldCast(String.class, \"leaf1\", "
223                     + ARG_AS_FOO_GRP + ".getLeaf1());"),
224                 tripleTab("this._leafList1 = CodeHelpers.checkSetFieldCast(String.class, \"leafList1\", "
225                     + ARG_AS_FOO_GRP + ".getLeafList1());"),
226                 tripleTab("this._leaf2 = " + ARG_AS_FOO_GRP + ".getLeaf2();"),
227                 TTAB_SET_IS_VALID_ARG_TRUE,
228                 DTAB_CLOSING_METHOD_BRACE,
229                 doubleTab("if (arg instanceof " + RESOLVED_LEAF_GRP_REF + ") {"),
230                 tripleTab("this._name = ((" + RESOLVED_LEAF_GRP_REF + ")arg).getName();"),
231                 TTAB_SET_IS_VALID_ARG_TRUE,
232                 DTAB_CLOSING_METHOD_BRACE,
233                 doubleTab("CodeHelpers.validValue(isValidArg, arg, \"[" + FOO_GRP_REF + ", " + RESOLVED_LEAF_GRP_REF
234                     + "]\");"),
235                 TAB_CLOSING_METHOD_BRACE);
236     }
237
238     private static void barContBuilderConstructorFooGrpTest(final File file, final String content) {
239         FileSearchUtil.assertFileContainsConsecutiveLines(file, content,
240                 tab("public BarContBuilder(" + FOO_GRP_REF + " arg) {"),
241                 doubleTab("this._leaf1 = CodeHelpers.checkFieldCast(String.class, \"leaf1\", "
242                     + "arg.getLeaf1());"),
243                 doubleTab("this._leafList1 = CodeHelpers.checkSetFieldCast(String.class, \"leafList1\", "
244                     + "arg.getLeafList1());"),
245                 doubleTab(LEAF2_ASSIGNMENT),
246                 TAB_CLOSING_METHOD_BRACE);
247     }
248
249     @Test
250     public void booleanContBuilderDataObjectTest() throws IOException {
251         final File file = files.get(getJavaBuilderFileName(BOOLEAN_CONT));
252         final String content = Files.readString(file.toPath());
253
254         booleanContBuilderFieldsFromTest(file, content);
255         booleanContBuilderConstructorTest(file, content);
256     }
257
258     private static void booleanContBuilderFieldsFromTest(final File file, final String content) {
259         FileSearchUtil.assertFileContainsConsecutiveLines(file, content,
260                 TAB_FIELDS_FROM_SIGNATURE,
261                 DTAB_INIT_IS_VALID_ARG_FALSE,
262                 doubleTab("if (arg instanceof " + UNRESOLVED_GROUPING_REF + ") {"),
263                 tripleTab("this._leaf1 = CodeHelpers.checkFieldCast(Boolean.class, \"leaf1\", (("
264                     + UNRESOLVED_GROUPING_REF + ")arg).getLeaf1());"),
265                 TTAB_SET_IS_VALID_ARG_TRUE,
266                 DTAB_CLOSING_METHOD_BRACE,
267                 doubleTab("CodeHelpers.validValue(isValidArg, arg, \"[" + UNRESOLVED_GROUPING_REF + "]\");"),
268                 TAB_CLOSING_METHOD_BRACE);
269     }
270
271     private static void booleanContBuilderConstructorTest(final File file, final String content) {
272         FileSearchUtil.assertFileContainsConsecutiveLines(file, content,
273                 tab("public BooleanContBuilder(" + UNRESOLVED_GROUPING_REF + " arg) {"),
274                 doubleTab("this._leaf1 = CodeHelpers.checkFieldCast(Boolean.class, \"leaf1\", "
275                     + "arg.getLeaf1());"),
276                 TAB_CLOSING_METHOD_BRACE);
277     }
278
279     private static String getJavaFileName(final String name) {
280         return name + ".java";
281     }
282
283     private static String getJavaBuilderFileName(final String name) {
284         return getJavaFileName(name + BindingMapping.BUILDER_SUFFIX);
285     }
286
287     private String getFileContent(final String fileName) throws IOException {
288         final File file = files.get(getJavaFileName(fileName));
289         assertNotNull(Files.lines(file.toPath()).findFirst());
290         final String content = Files.readString(Path.of(file.getAbsolutePath()));
291         assertNotNull(content);
292         return content;
293     }
294
295     private void verifyMethodAbsence(final String typeName, final String getterName) {
296         verifyReturnType(typeName, getterName, null);
297     }
298
299     private void verifyReturnType(final String typeName, final String getterName, final Type returnType) {
300         final GeneratedType generated = typeByName(types, typeName);
301         assertNotNull(generated);
302         assertEquals(returnType, returnTypeByMethodName(generated, getterName));
303     }
304
305     private static GeneratedType typeByName(final List<GeneratedType> types, final String name) {
306         for (final GeneratedType type : types) {
307             if (type.getName().equals(name)) {
308                 return type;
309             }
310         }
311         return null;
312     }
313
314     private static Type returnTypeByMethodName(final GeneratedType type, final String name) {
315         for (final MethodSignature m : type.getMethodDefinitions()) {
316             if (m.getName().equals(name)) {
317                 return m.getReturnType();
318             }
319         }
320         return null;
321     }
322 }