1
1
package spoon .test .record ;
2
2
3
3
import static java .lang .System .lineSeparator ;
4
- import static org .hamcrest .CoreMatchers .equalTo ;
5
- import static org .hamcrest .MatcherAssert .assertThat ;
6
4
import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
7
5
import static org .junit .jupiter .api .Assertions .assertEquals ;
8
6
import static org .junit .jupiter .api .Assertions .assertFalse ;
9
7
import static org .junit .jupiter .api .Assertions .assertTrue ;
8
+ import static spoon .testing .assertions .SpoonAssertions .assertThat ;
9
+ import static org .assertj .core .api .Assertions .assertThat ;
10
+
10
11
import java .util .Arrays ;
11
12
import java .util .Collection ;
12
13
import java .util .Comparator ;
15
16
import java .util .stream .Collectors ;
16
17
import javax .validation .constraints .NotNull ;
17
18
19
+ import org .assertj .core .api .InstanceOfAssertFactory ;
18
20
import org .junit .jupiter .api .Test ;
19
21
import spoon .Launcher ;
20
22
import spoon .reflect .CtModel ;
23
+ import spoon .reflect .code .CtFieldRead ;
24
+ import spoon .reflect .code .CtReturn ;
25
+ import spoon .reflect .code .CtStatement ;
21
26
import spoon .reflect .declaration .CtAnonymousExecutable ;
22
27
import spoon .reflect .declaration .CtConstructor ;
28
+ import spoon .reflect .declaration .CtElement ;
23
29
import spoon .reflect .declaration .CtField ;
24
30
import spoon .reflect .declaration .CtMethod ;
25
31
import spoon .reflect .declaration .CtRecord ;
32
+ import spoon .reflect .declaration .CtRecordComponent ;
26
33
import spoon .reflect .declaration .CtType ;
27
34
import spoon .reflect .factory .Factory ;
35
+ import spoon .reflect .visitor .CtScanner ;
28
36
import spoon .reflect .visitor .filter .TypeFilter ;
37
+ import spoon .testing .assertions .SpoonAssertions ;
29
38
import spoon .testing .utils .ModelTest ;
30
39
31
40
public class CtRecordTest {
@@ -76,24 +85,33 @@ public void testMultipleParameterRecord() {
76
85
77
86
assertEquals (1 , records .size ());
78
87
assertEquals ("public record MultiParameter(int first, float second) {}" , head (records ).toString ());
79
-
88
+
80
89
// test fields
81
90
assertEquals (
82
91
Arrays .asList (
83
- "private final int first;" ,
92
+ "private final int first;" ,
84
93
"private final float second;"
85
- ),
94
+ ),
86
95
head (records ).getFields ().stream ().map (String ::valueOf ).collect (Collectors .toList ())
87
96
);
88
-
97
+
98
+ // Make them explicit so we can print them (but assert they were implicit initially)
99
+ assertThat (head (records )).getMethods ().allSatisfy (CtElement ::isImplicit );
100
+ head (records ).getMethods ().forEach (it -> it .accept (new CtScanner () {
101
+ @ Override
102
+ protected void enter (CtElement e ) {
103
+ e .setImplicit (false );
104
+ }
105
+ }));
106
+
89
107
// test methods
90
108
assertEquals (
91
109
Arrays .asList (
92
110
"int first() {\n " +
93
- " return first;\n " +
94
- "}" ,
111
+ " return this. first;\n " +
112
+ "}" ,
95
113
"float second() {\n " +
96
- " return second;\n " +
114
+ " return this. second;\n " +
97
115
"}"
98
116
),
99
117
head (records ).getMethods ().stream ()
@@ -211,7 +229,7 @@ private CtModel createModelFromPath(String code) {
211
229
212
230
@ Test
213
231
void testGenericTypeParametersArePrintedBeforeTheFunctionParameters () {
214
- // contract: a record with generic type arguments should be printed correctly
232
+ // contract: a record with generic type arguments should be printed correctly
215
233
String code = "src/test/resources/records/GenericRecord.java" ;
216
234
CtModel model = createModelFromPath (code );
217
235
Collection <CtRecord > records = model .getElements (new TypeFilter <>(CtRecord .class ));
@@ -225,7 +243,7 @@ void testBuildRecordModelWithStaticInitializer() {
225
243
String code = "src/test/resources/records/WithStaticInitializer.java" ;
226
244
CtModel model = assertDoesNotThrow (() -> createModelFromPath (code ));
227
245
List <CtAnonymousExecutable > execs = model .getElements (new TypeFilter <>(CtAnonymousExecutable .class ));
228
- assertThat (execs . size (), equalTo ( 2 ) );
246
+ assertThat (execs ). hasSize ( 2 );
229
247
}
230
248
231
249
@ ModelTest (value = "./src/test/resources/records/MultipleConstructors.java" , complianceLevel = 16 )
@@ -275,8 +293,29 @@ void testNonCompactCanonicalConstructor(Factory factory) {
275
293
assertEquals (constructor .getParameters ().get (0 ).getSimpleName (), "x" );
276
294
}
277
295
296
+ @ ModelTest (value = "./src/test/resources/records/GenericRecord.java" , complianceLevel = 16 )
297
+ void testProperReturnInRecordAccessor (Factory factory ) {
298
+ // contract: the return statement in the accessor method should return a field read expression to the correct
299
+ // field
300
+ CtRecord record = head (factory .getModel ().getElements (new TypeFilter <>(CtRecord .class )));
301
+
302
+ assertThat (record .getRecordComponents ()).isNotEmpty ();
303
+ for (CtRecordComponent component : record .getRecordComponents ()) {
304
+ CtMethod <?> method = component .toMethod ();
305
+
306
+ assertThat (method .getBody ().<CtStatement >getLastStatement ())
307
+ .asInstanceOf (new InstanceOfAssertFactory <>(CtReturn .class , SpoonAssertions ::assertThat ))
308
+ .getReturnedExpression ()
309
+ .self ()
310
+ .asInstanceOf (new InstanceOfAssertFactory <>(CtFieldRead .class , SpoonAssertions ::assertThat ))
311
+ .getVariable ()
312
+ .getDeclaringType ()
313
+ .getSimpleName ()
314
+ .isEqualTo (record .getSimpleName ());
315
+ }
316
+ }
317
+
278
318
private <T > T head (Collection <T > collection ) {
279
319
return collection .iterator ().next ();
280
320
}
281
-
282
321
}
0 commit comments