1 package net.sourceforge.jenesis4java.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import net.sourceforge.jenesis4java.*;
26 import net.sourceforge.jenesis4java.util.DeclarationBaseTest;
27 import net.sourceforge.jenesis4java.util.InstanceReplacingVisitor;
28 import net.sourceforge.jenesis4java.util.StatementTestBase;
29 import net.sourceforge.jenesis4java.util.WithVmAndPackageClass;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.experimental.runners.Enclosed;
33 import org.junit.runner.RunWith;
34
35 import java.util.Arrays;
36 import java.util.Collections;
37
38 import static net.sourceforge.jenesis4java.Constructor.ForwardingTarget.SUPER;
39 import static net.sourceforge.jenesis4java.Constructor.ForwardingTarget.THIS;
40 import static net.sourceforge.jenesis4java.impl.CommentsTest.MultiLineComment.DEFAULT_MULTILINE_COMMENT;
41 import static net.sourceforge.jenesis4java.util.CodeGenerationAssertions.*;
42 import static net.sourceforge.jenesis4java.util.Shortcuts.dummyClass;
43 import static net.sourceforge.jenesis4java.util.TestHelper.LS;
44 import static org.junit.Assert.assertEquals;
45 import static org.junit.Assert.assertNull;
46 import static org.junit.Assert.assertSame;
47
48 @RunWith(Enclosed.class)
49 public class ConstructorTest {
50
51 public static class BasicSyntax extends WithVmAndPackageClass {
52
53 @Test
54 public void emptyConstructor() {
55 assertEqualsIgnoreLineBreaks("Dummy() {}", packageClass.newConstructor().toString());
56 }
57
58 @Test
59 public void accessModifier() {
60 Constructor constructor = packageClass.newConstructor();
61 constructor.setAccess(Access.PUBLIC);
62 assertEqualsIgnoreLineBreaks("public Dummy() {}", constructor.toString());
63 }
64
65 @Test
66 public void singleParameter() {
67 Constructor constructor = packageClass.newConstructor();
68 constructor.addParameter(String.class, "name");
69 assertEqualsIgnoreLineBreaks("Dummy(String name) {}", constructor.toString());
70 }
71
72 @Test
73 public void multipleParameters() {
74 Constructor constructor = packageClass.newConstructor();
75 constructor.addParameter(String.class, "name");
76 constructor.addParameter(vm.type_int(), "size");
77 assertEqualsIgnoreLineBreaks("Dummy(String name, int size) {}", constructor.toString());
78 }
79
80 @Test
81 public void singleException() {
82 Constructor constructor = packageClass.newConstructor();
83 constructor.addThrows("Exception");
84 assertEqualsIgnoreLineBreaks("Dummy() throws Exception {}", constructor.toString());
85 }
86
87 @Test
88 public void multipleExceptions() {
89 Constructor constructor = packageClass.newConstructor();
90 constructor.addThrows("IOException");
91 constructor.addThrows("OwnException");
92 assertEqualsIgnoreLineBreaks("Dummy() throws IOException, OwnException {}", constructor.toString());
93 }
94 }
95
96 public static class Getters extends WithVmAndPackageClass {
97
98 @Test
99 public void nothingSet() {
100 Constructor constructor = packageClass.newConstructor();
101 assertEquals(Collections.emptyList(), constructor.getParameters());
102 assertEquals(Collections.emptyList(), constructor.getThrows());
103 }
104
105 @Test
106 public void setParameters() {
107 Constructor constructor = packageClass.newConstructor();
108 FormalParameter formalParameter1 = constructor.addParameter(String.class, "1");
109 FormalParameter formalParameter2 = constructor.addParameter(String.class, "2");
110 assertEquals(Arrays.asList(formalParameter1, formalParameter2), constructor.getParameters());
111 assertEquals(Collections.emptyList(), constructor.getThrows());
112 }
113
114 @Test
115 public void setThrows() {
116 Constructor constructor = packageClass.newConstructor();
117 constructor.addThrows("X").addThrows("Y");
118 assertEquals(Collections.emptyList(), constructor.getParameters());
119 assertEquals(Arrays.asList("X", "Y"), constructor.getThrows());
120 }
121 }
122
123 public static class InheritedFunctionality extends DeclarationBaseTest {
124
125 @Override
126 public Declaration getInstance() {
127 return dummyClass().newConstructor();
128 }
129 }
130
131 public static class TestConstructorForwarding {
132
133 private Constructor constructor;
134
135 private VirtualMachine vm;
136
137 @Before
138 public void setUp() {
139 vm = VirtualMachine.getVirtualMachine();
140 constructor = dummyClass().newConstructor();
141 }
142
143 @Test
144 public void superNoArgs() {
145 constructor.forwardCall(SUPER);
146 assertInsideBlock("super();", constructor);
147 }
148
149 @Test
150 public void thisNoArgs() {
151 constructor.forwardCall(THIS);
152 assertInsideBlock("this();", constructor);
153 }
154
155 @Test
156 public void thisOverwritesSuper() {
157 constructor.forwardCall(SUPER);
158 constructor.forwardCall(THIS);
159 assertInsideBlock("this();", constructor);
160 }
161
162 @Test
163 public void superOverwritesThis() {
164 constructor.forwardCall(THIS);
165 constructor.forwardCall(SUPER);
166 assertInsideBlock("super();", constructor);
167 }
168
169 @Test
170 public void thisBeforeOtherStatements() {
171 Statement stmt = constructor.newStmt(vm.newFree("expression"));
172 constructor.forwardCall(SUPER);
173 assertInsideBlock("super();" + LS + stmt.toString(), constructor);
174 }
175
176 @Test
177 public void nullOverwritesForwarding() {
178 String constructorWithoutAnyForwarding = constructor.toString();
179 constructor.forwardCall(THIS);
180
181 ConstructorForwarding constructorForwarding = constructor.forwardCall(null);
182 assertNull(constructorForwarding);
183 assertEquals(constructorWithoutAnyForwarding, constructor.toString());
184 }
185
186 @Test
187 public void withTrailingComment() {
188 assertThatTrailingCommentIsOnSameLine(constructor.forwardCall(THIS));
189 }
190
191 @Test
192 public void withBlockComment() {
193 ConstructorForwarding thisForwarding = constructor.forwardCall(THIS);
194 String withoutComment = thisForwarding.toString();
195 thisForwarding.setComment(Comment.MULTI_LINE, "comment");
196 assertEquals(DEFAULT_MULTILINE_COMMENT + withoutComment, thisForwarding.toString());
197 }
198
199 @Test
200 public void oneArgument() {
201 ConstructorForwarding thisForwarding = constructor.forwardCall(THIS);
202 ConstructorForwarding returned = thisForwarding.addVariableArg("var");
203 assertEquals("this(var);", thisForwarding.toString());
204 assertSame(thisForwarding, returned);
205 }
206
207 @Test
208 public void severalArgumentsWithChaining() {
209 ConstructorForwarding superForwarding = constructor.forwardCall(SUPER);
210 ConstructorForwarding returned =
211 superForwarding.addArg(true)
212 .addArg(0.1d)
213 .addArg(vm.newFree("free"))
214 .addArg(1.23f)
215 .addArg(123)
216 .addArg(456L)
217 .addArg("string");
218
219 assertEquals(7, superForwarding.getArgs().size());
220 assertEquals("super(true, 0.1D, free, 1.23F, 123, 456L, \"string\");", superForwarding.toString());
221 assertSame(superForwarding, returned);
222 }
223
224 @Test
225 public void removeArg() {
226 ConstructorForwarding superForwarding = constructor.forwardCall(SUPER);
227 String beforeAddRemove = superForwarding.toString();
228 superForwarding.addArg(true).removeArg(0);
229 String afterAddRemove = superForwarding.toString();
230 assertEquals(beforeAddRemove, afterAddRemove);
231 }
232
233 @Test(expected = IllegalArgumentException.class)
234 public void removeArgTooBig() {
235 ConstructorForwarding superForwarding = constructor.forwardCall(SUPER);
236 superForwarding.addArg("1");
237 superForwarding.removeArg(1);
238 }
239
240 @Test(expected = IllegalArgumentException.class)
241 public void removeArgTooSmall() {
242 ConstructorForwarding superForwarding = constructor.forwardCall(SUPER);
243 superForwarding.removeArg(-1);
244 }
245
246 @Test
247 public void getForwardingTarget() {
248 assertEquals(SUPER, constructor.forwardCall(SUPER).getTarget());
249 assertEquals(THIS, constructor.forwardCall(THIS).getTarget());
250 }
251
252 @Test
253 public void useQualifier() {
254 ConstructorForwarding superForwarding = constructor.forwardCall(THIS);
255 superForwarding.setQualifier("Outer");
256 assertEquals("Outer.this();", superForwarding.toString());
257 }
258
259 @Test
260 public void setAndGetQualifier() {
261 ConstructorForwarding superForwarding = constructor.forwardCall(THIS);
262 superForwarding.setQualifier("Outer");
263 assertEquals(vm.newClassLiteral("Outer").toString(), superForwarding.getQualifier().toString());
264
265 }
266
267 @Test
268 public void noQualifier() {
269 ConstructorForwarding superForwarding = constructor.forwardCall(THIS);
270 assertNull(superForwarding.getQualifier());
271 }
272 }
273
274 public static class ConstructorForwardingInheritedFunctionality extends StatementTestBase {
275
276 @Override
277 public Statement getInstance() {
278 return dummyClass().newConstructor().forwardCall(THIS);
279 }
280 }
281
282 public static class Visitor extends WithVmAndPackageClass {
283
284 @Test
285 public void replaceForwarding() {
286 Constructor constructor = packageClass.newConstructor();
287 ConstructorForwarding superForward = constructor.forwardCall(SUPER);
288 ConstructorForwarding thisForward = constructor.forwardCall(THIS);
289 constructor.visit(new InstanceReplacingVisitor(thisForward, superForward));
290 assertInsideBlock("super();", constructor);
291 }
292
293 @Test
294 public void replaceArgInConstructorForwarding() {
295 Constructor constructor = packageClass.newConstructor();
296 ConstructorForwarding superForward = constructor.forwardCall(SUPER);
297 Expression original = vm.newFree("original");
298 superForward.addArg(original);
299
300 Expression replacement = vm.newFree("replacement");
301 superForward.visit(new InstanceReplacingVisitor(original, replacement));
302 assertEquals(Collections.singletonList(replacement), superForward.getArgs());
303 }
304
305 }
306 }