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