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