1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.metalava.model.testsuite.fielditem
18 
19 import com.android.tools.metalava.model.testsuite.BaseModelTest
20 import com.android.tools.metalava.testing.java
21 import kotlin.test.assertEquals
22 import kotlin.test.assertNotNull
23 import org.junit.Test
24 
25 /** Common tests for [FieldItem.InitialValue]. */
26 class SourceFieldItemTest : BaseModelTest() {
27 
28     @Test
test field with default value as constant literalnull29     fun `test field with default value as constant literal`() {
30         runSourceCodebaseTest(
31             java(
32                 """
33                     package test.pkg;
34 
35                     public class Test {
36                         public int field0;
37                         public static final boolean field1 = true;
38                         public static final long field2 = 5L;
39                         public static final float field3 = 98.5f;
40                         public static final String field4 = "String with \"escapes\" and \u00a9...";
41                         public static final double field5 = Double.POSITIVE_INFINITY;
42                         public static final char field6 = 61184;
43                     }
44                 """
45             ),
46         ) {
47             val classItem = codebase.assertClass("test.pkg.Test")
48             val fieldValues =
49                 listOf(
50                     null,
51                     true,
52                     5L,
53                     98.5f,
54                     "String with \"escapes\" and \u00a9...",
55                     Double.POSITIVE_INFINITY,
56                     61184.toChar(),
57                 )
58             assertEquals(fieldValues, classItem.fields().map { it.initialValue(false) })
59             assertEquals(fieldValues, classItem.fields().map { it.initialValue(true) })
60         }
61     }
62 
63     @Test
test field with default value as constant expressionnull64     fun `test field with default value as constant expression`() {
65         runCodebaseTest(
66             java(
67                 """
68                       package test.pkg;
69 
70                       public class Test {
71                           public static final int field1 = 5*7+3;
72                           public static final int field2 = EXPR_FIELD1+EXPR_FIELD2;
73                           public static final int EXPR_FIELD1 = 47;
74                           public static final int EXPR_FIELD2 = 44;
75                       }
76                   """
77             ),
78         ) {
79             val classItem = codebase.assertClass("test.pkg.Test")
80             val fieldItem1 = classItem.assertField("field1")
81             val fieldItem2 = classItem.assertField("field2")
82             assertEquals(38, fieldItem1.initialValue(true))
83             assertEquals(38, fieldItem1.initialValue(false))
84             assertEquals(91, fieldItem2.initialValue(true))
85             assertEquals(91, fieldItem2.initialValue(false))
86         }
87     }
88 
89     @Test
test field with default value as object referencenull90     fun `test field with default value as object reference`() {
91         runSourceCodebaseTest(
92             java(
93                 """
94                     package test.pkg;
95 
96                     public class Test {
97                         public static final Test1 field1 = Test1.ENUM1;
98                         public static final Test2 field2 = new Test2();
99                     }
100 
101                     enum Test1 {
102                         ENUM1,
103                         ENUM2,
104                         ENUM3,
105                     }
106 
107                     class Test2 {}
108                 """
109             ),
110         ) {
111             val classItem = codebase.assertClass("test.pkg.Test")
112             val fieldItem1 = classItem.assertField("field1")
113             val fieldItem2 = classItem.assertField("field2")
114 
115             assertEquals(null, fieldItem1.initialValue(false))
116             assertEquals(null, fieldItem1.initialValue(true))
117             assertEquals(null, fieldItem2.initialValue(true))
118             assertEquals(null, fieldItem2.initialValue(false))
119         }
120     }
121 
122     @Test
test default value of an enum constant fieldnull123     fun `test default value of an enum constant field`() {
124         runSourceCodebaseTest(
125             java(
126                 """
127                     package test.pkg;
128 
129                     public enum Test {
130                         ENUM1,
131                         ENUM2,
132                     }
133                 """
134             ),
135         ) {
136             val classItem = codebase.assertClass("test.pkg.Test")
137             val fieldItem = classItem.assertField("ENUM1")
138 
139             assertNotNull(fieldItem.initialValue(true))
140             assertNotNull(fieldItem.initialValue(false))
141         }
142     }
143 
144     @Test
test default value of a Class type fieldnull145     fun `test default value of a Class type field`() {
146         runSourceCodebaseTest(
147             java(
148                 """
149                     package test.pkg;
150 
151                     public class Test {
152                         public static final Class<?> field = String.class;;
153                     }
154                 """
155             ),
156         ) {
157             val classItem = codebase.assertClass("test.pkg.Test")
158             val fieldItem = classItem.assertField("field")
159             assertEquals(null, fieldItem.initialValue(true))
160             assertNotNull(fieldItem.initialValue(false))
161         }
162     }
163 
164     @Test
test non final field with default value as constant literalnull165     fun `test non final field with default value as constant literal`() {
166         runSourceCodebaseTest(
167             java(
168                 """
169                     package test.pkg;
170 
171                     public class Test {
172                         public static int field = 7;
173                     }
174                 """
175             ),
176         ) {
177             val classItem = codebase.assertClass("test.pkg.Test")
178             val fieldItem = classItem.assertField("field")
179 
180             assertEquals(null, fieldItem.initialValue(true))
181             assertEquals(7, fieldItem.initialValue(false))
182         }
183     }
184 
185     @Test
test non final field with default value as constant expressionnull186     fun `test non final field with default value as constant expression`() {
187         runSourceCodebaseTest(
188             java(
189                 """
190                     package test.pkg;
191 
192                     public class Test {
193                         public static int field1 = 7*3+6;
194                         public static int field2 = EXPR_FIELD1+EXPR_FIELD2;
195                         public static final int EXPR_FIELD1 = 47;
196                         public static final int EXPR_FIELD2 = 44;
197                     }
198                 """
199             ),
200         ) {
201             val classItem = codebase.assertClass("test.pkg.Test")
202             val fieldItem1 = classItem.assertField("field1")
203             val fieldItem2 = classItem.assertField("field2")
204 
205             assertEquals(null, fieldItem1.initialValue(true))
206             assertEquals(27, fieldItem1.initialValue(false))
207             assertEquals(null, fieldItem2.initialValue(true))
208             assertEquals(91, fieldItem2.initialValue(false))
209         }
210     }
211 
212     @Test
test default value of a non final Class type fieldnull213     fun `test default value of a non final Class type field`() {
214         runSourceCodebaseTest(
215             java(
216                 """
217                     package test.pkg;
218 
219                     public class Test {
220                         public static Class<?> field = String.class;;
221                     }
222                 """
223             ),
224         ) {
225             val classItem = codebase.assertClass("test.pkg.Test")
226             val fieldItem = classItem.assertField("field")
227             assertEquals(null, fieldItem.initialValue(true))
228             assertNotNull(fieldItem.initialValue(false))
229         }
230     }
231 
232     @Test
test duplicate() for fielditemnull233     fun `test duplicate() for fielditem`() {
234         runSourceCodebaseTest(
235             java(
236                 """
237                     package test.pkg;
238 
239                     /** @doconly Some docs here */
240                     public class Test {
241                         public static final int Field = 7;
242                     }
243 
244                     /** @hide */
245                     public class Target {}
246                 """
247             ),
248         ) {
249             val classItem = codebase.assertClass("test.pkg.Test")
250             val targetClassItem = codebase.assertClass("test.pkg.Target")
251             val fieldItem = classItem.assertField("Field")
252 
253             val duplicateField = fieldItem.duplicate(targetClassItem)
254 
255             assertEquals(
256                 fieldItem.modifiers.getVisibilityLevel(),
257                 duplicateField.modifiers.getVisibilityLevel()
258             )
259             assertEquals(true, fieldItem.modifiers.equivalentTo(duplicateField.modifiers))
260             assertEquals(true, duplicateField.hidden)
261             assertEquals(false, duplicateField.docOnly)
262             assertEquals(fieldItem.type(), duplicateField.type())
263             assertEquals(fieldItem.initialValue(), duplicateField.initialValue())
264             assertEquals(classItem, duplicateField.inheritedFrom)
265         }
266     }
267 }
268