1 /*
<lambda>null2  * Copyright 2025 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 androidx.appfunctions.metadata
18 
19 import androidx.appfunctions.metadata.AppFunctionPrimitiveTypeMetadata.Companion.TYPE_INT
20 import androidx.appfunctions.metadata.AppFunctionPrimitiveTypeMetadata.Companion.TYPE_LONG
21 import androidx.appfunctions.metadata.AppFunctionPrimitiveTypeMetadata.Companion.TYPE_STRING
22 import com.google.common.truth.Truth.assertThat
23 import org.junit.Test
24 
25 class AppFunctionDataTypeMetadataTest {
26 
27     @Test
28     fun appFunctionArrayTypeMetadata_equalsAndHashCode() {
29         val properties2 = mapOf("prop2" to AppFunctionPrimitiveTypeMetadata(TYPE_STRING, true))
30 
31         val arrayType1a =
32             AppFunctionArrayTypeMetadata(AppFunctionPrimitiveTypeMetadata(TYPE_INT, true), false)
33         val arrayType1b =
34             AppFunctionArrayTypeMetadata(AppFunctionPrimitiveTypeMetadata(TYPE_INT, true), false)
35         val arrayType2 =
36             AppFunctionArrayTypeMetadata(
37                 AppFunctionObjectTypeMetadata(properties2, emptyList(), "qualifiedName", false),
38                 false
39             )
40 
41         assertThat(arrayType1a).isEqualTo(arrayType1b)
42         assertThat(arrayType1a.hashCode()).isEqualTo(arrayType1b.hashCode())
43 
44         assertThat(arrayType1a).isNotEqualTo(arrayType2)
45         assertThat(arrayType1a.hashCode()).isNotEqualTo(arrayType2.hashCode())
46     }
47 
48     @Test
49     fun appFunctionArrayTypeMetadata_toAppFunctionDataTypeMetadataDocument_returnsCorrectDocument() {
50         val arrayType =
51             AppFunctionArrayTypeMetadata(AppFunctionPrimitiveTypeMetadata(TYPE_INT, true), false)
52 
53         val document = arrayType.toAppFunctionDataTypeMetadataDocument()
54 
55         assertThat(document)
56             .isEqualTo(
57                 AppFunctionDataTypeMetadataDocument(
58                     type = AppFunctionArrayTypeMetadata.TYPE,
59                     itemType =
60                         AppFunctionDataTypeMetadataDocument(
61                             type = TYPE_INT,
62                             isNullable = true,
63                         ),
64                     isNullable = false,
65                 )
66             )
67     }
68 
69     @Test
70     fun appFunctionAllOfTypeMetadata_equalsAndHashCode() {
71         val properties1 = mapOf("prop1" to AppFunctionPrimitiveTypeMetadata(TYPE_INT, false))
72         val objectType =
73             AppFunctionObjectTypeMetadata(properties1, listOf("prop1"), "qualifiedName", false)
74         val referenceType = AppFunctionReferenceTypeMetadata("type1", false)
75         val allOfDataType1 =
76             AppFunctionAllOfTypeMetadata(
77                 matchAll = listOf(objectType),
78                 isNullable = true,
79                 qualifiedName = null
80             )
81         val allOfDataType2 =
82             AppFunctionAllOfTypeMetadata(
83                 matchAll = listOf(objectType, referenceType),
84                 isNullable = true,
85                 qualifiedName = "allOf1"
86             )
87         val allOfDataType2a =
88             AppFunctionAllOfTypeMetadata(
89                 matchAll = listOf(objectType, referenceType),
90                 isNullable = true,
91                 qualifiedName = "allOf1"
92             )
93 
94         assertThat(allOfDataType1).isNotEqualTo(allOfDataType2)
95         assertThat(allOfDataType1.hashCode()).isNotEqualTo(allOfDataType2.hashCode())
96 
97         assertThat(allOfDataType2).isEqualTo(allOfDataType2a)
98         assertThat(allOfDataType2.hashCode()).isEqualTo(allOfDataType2a.hashCode())
99     }
100 
101     @Test
102     fun appFunctionAllOfTypeMetadata_toAppFunctionDatatypeMetadataDocument_returnsCorrectDocument() {
103         val properties1 = mapOf("prop1" to AppFunctionPrimitiveTypeMetadata(TYPE_INT, false))
104         val objectType =
105             AppFunctionObjectTypeMetadata(properties1, listOf("prop1"), "qualifiedName", false)
106         val referenceType = AppFunctionReferenceTypeMetadata("type1", false)
107         val allOfDataType =
108             AppFunctionAllOfTypeMetadata(
109                 matchAll = listOf(referenceType, objectType),
110                 isNullable = true,
111                 qualifiedName = "allOf1"
112             )
113 
114         val document = allOfDataType.toAppFunctionDataTypeMetadataDocument()
115 
116         assertThat(document.allOf)
117             .containsExactly(
118                 referenceType.toAppFunctionDataTypeMetadataDocument(),
119                 objectType.toAppFunctionDataTypeMetadataDocument()
120             )
121         assertThat(document.type).isEqualTo(AppFunctionAllOfTypeMetadata.TYPE)
122         assertThat(document.isNullable).isTrue()
123         assertThat(document.dataTypeReference).isNull()
124         assertThat(document.itemType).isNull()
125         assertThat(document.properties).isEmpty()
126         assertThat(document.objectQualifiedName).isNotEmpty()
127         assertThat(document.objectQualifiedName).isEqualTo("allOf1")
128     }
129 
130     @Test
131     fun appFunctionObjectTypeMetadata_equalsAndHashCode() {
132         val properties1 = mapOf("prop1" to AppFunctionPrimitiveTypeMetadata(TYPE_INT, false))
133         val properties2 = mapOf("prop2" to AppFunctionPrimitiveTypeMetadata(TYPE_STRING, true))
134 
135         val objectType1a =
136             AppFunctionObjectTypeMetadata(properties1, listOf("prop1"), "qualifiedName", false)
137         val objectType1b =
138             AppFunctionObjectTypeMetadata(properties1, listOf("prop1"), "qualifiedName", false)
139         val objectType2 =
140             AppFunctionObjectTypeMetadata(properties2, listOf("prop2"), "qualifiedName", true)
141 
142         assertThat(objectType1a).isEqualTo(objectType1b)
143         assertThat(objectType1a.hashCode()).isEqualTo(objectType1b.hashCode())
144 
145         assertThat(objectType1a).isNotEqualTo(objectType2)
146         assertThat(objectType1a.hashCode()).isNotEqualTo(objectType2.hashCode())
147     }
148 
149     @Test
150     fun appFunctionObjectTypeMetadata_toAppFunctionDataTypeMetadataDocument_returnsCorrectDocument() {
151         val primitiveTypeInt = AppFunctionPrimitiveTypeMetadata(TYPE_INT, true)
152         val primitiveTypeLong = AppFunctionPrimitiveTypeMetadata(TYPE_LONG, false)
153         val properties =
154             mapOf(
155                 "prop1" to primitiveTypeInt,
156                 "prop2" to primitiveTypeLong,
157             )
158         val isNullable = false
159         val qualifiedName = "qualifiedName"
160         val requiredProperties = listOf("prop1", "prop2")
161         val appFunctionObjectTypeMetadata =
162             AppFunctionObjectTypeMetadata(properties, requiredProperties, qualifiedName, isNullable)
163 
164         val convertedDocument =
165             appFunctionObjectTypeMetadata.toAppFunctionDataTypeMetadataDocument()
166 
167         val expectedPrimitiveDocumentProperties1 =
168             AppFunctionNamedDataTypeMetadataDocument(
169                 name = "prop1",
170                 dataTypeMetadata =
171                     AppFunctionDataTypeMetadataDocument(type = TYPE_INT, isNullable = true)
172             )
173         val expectedPrimitiveDocumentProperties2 =
174             AppFunctionNamedDataTypeMetadataDocument(
175                 name = "prop2",
176                 dataTypeMetadata =
177                     AppFunctionDataTypeMetadataDocument(type = TYPE_LONG, isNullable = false)
178             )
179         val expectedAppFunctionDataTypeMetadataDocument =
180             AppFunctionDataTypeMetadataDocument(
181                 type = AppFunctionObjectTypeMetadata.TYPE,
182                 properties =
183                     listOf(
184                         expectedPrimitiveDocumentProperties1,
185                         expectedPrimitiveDocumentProperties2,
186                     ),
187                 required = requiredProperties,
188                 objectQualifiedName = "qualifiedName",
189                 isNullable = false,
190             )
191         assertThat(convertedDocument).isEqualTo(expectedAppFunctionDataTypeMetadataDocument)
192     }
193 
194     @Test
195     fun appFunctionReferenceTypeMetadata_equalsAndHashCode() {
196         val ref1a = AppFunctionReferenceTypeMetadata("type1", false)
197         val ref1b = AppFunctionReferenceTypeMetadata("type1", false)
198         val ref2 = AppFunctionReferenceTypeMetadata("type2", true)
199 
200         assertThat(ref1a).isEqualTo(ref1b)
201         assertThat(ref1a.hashCode()).isEqualTo(ref1b.hashCode())
202 
203         assertThat(ref1a).isNotEqualTo(ref2)
204         assertThat(ref1a.hashCode()).isNotEqualTo(ref2.hashCode())
205     }
206 
207     @Test
208     fun appFunctionReferenceTypeMetadata_toAppFunctionDataTypeMetadataDocument_returnsCorrectDocument() {
209         val referenceType =
210             AppFunctionReferenceTypeMetadata(
211                 referenceDataType = "#components/dataTypes/Test",
212                 isNullable = true,
213             )
214 
215         val document = referenceType.toAppFunctionDataTypeMetadataDocument()
216 
217         assertThat(document)
218             .isEqualTo(
219                 AppFunctionDataTypeMetadataDocument(
220                     type = AppFunctionReferenceTypeMetadata.TYPE,
221                     dataTypeReference = "#components/dataTypes/Test",
222                     isNullable = true,
223                 )
224             )
225     }
226 
227     @Test
228     fun appFunctionPrimitiveTypeMetadata_equalsAndHashCode() {
229         val primitive1a = AppFunctionPrimitiveTypeMetadata(TYPE_INT, false)
230         val primitive1b = AppFunctionPrimitiveTypeMetadata(TYPE_INT, false)
231         val primitive2 = AppFunctionPrimitiveTypeMetadata(TYPE_STRING, false)
232 
233         assertThat(primitive1a).isEqualTo(primitive1b)
234         assertThat(primitive1a.hashCode()).isEqualTo(primitive1b.hashCode())
235 
236         assertThat(primitive1a).isNotEqualTo(primitive2)
237         assertThat(primitive1a.hashCode()).isNotEqualTo(primitive2.hashCode())
238     }
239 
240     @Test
241     fun appFunctionPrimitiveTypeMetadata_toAppFunctionDataTypeMetadataDocument_returnsCorrectDocument() {
242         val primitiveTypeInt = AppFunctionPrimitiveTypeMetadata(TYPE_INT, true)
243         val primitiveTypeLong = AppFunctionPrimitiveTypeMetadata(TYPE_LONG, false)
244 
245         assertThat(primitiveTypeInt.toAppFunctionDataTypeMetadataDocument())
246             .isEqualTo(AppFunctionDataTypeMetadataDocument(type = TYPE_INT, isNullable = true))
247         assertThat(primitiveTypeLong.toAppFunctionDataTypeMetadataDocument())
248             .isEqualTo(AppFunctionDataTypeMetadataDocument(type = TYPE_LONG, isNullable = false))
249     }
250 
251     @Test
252     fun appFunctionDataTypeMetadataDocument_toAppFunctionPrimitiveTypeMetadata_returnsCorrectMetadata() {
253         // Test all primitive types. Only Parameterized TestRunner is allowed in AndroidX tests
254         // which injects at class level and all tests will run for each combination, hence manually
255         // iterating over the values.
256         AppFunctionDataTypeMetadata.PRIMITIVE_TYPES.forEach { type ->
257             val document = AppFunctionDataTypeMetadataDocument(type = type, isNullable = false)
258 
259             val metadata = document.toAppFunctionDataTypeMetadata()
260 
261             assertThat(metadata)
262                 .isEqualTo(AppFunctionPrimitiveTypeMetadata(type = type, isNullable = false))
263         }
264     }
265 
266     @Test
267     fun appFunctionDataTypeMetadataDocument_toAppFunctionArrayTypeMetadata_returnsCorrectMetadata() {
268         val document =
269             AppFunctionDataTypeMetadataDocument(
270                 type = AppFunctionDataTypeMetadata.TYPE_ARRAY,
271                 itemType =
272                     AppFunctionDataTypeMetadataDocument(
273                         type = AppFunctionDataTypeMetadata.TYPE_STRING,
274                         isNullable = false
275                     ),
276                 isNullable = true
277             )
278 
279         val metadata = document.toAppFunctionDataTypeMetadata()
280 
281         assertThat(metadata)
282             .isEqualTo(
283                 AppFunctionArrayTypeMetadata(
284                     itemType =
285                         AppFunctionPrimitiveTypeMetadata(
286                             type = AppFunctionDataTypeMetadata.TYPE_STRING,
287                             isNullable = false
288                         ),
289                     isNullable = true
290                 )
291             )
292     }
293 
294     @Test
295     fun appFunctionDataTypeMetadataDocument_toAppFunctionObjectTypeMetadata_returnsCorrectMetadata() {
296         val document =
297             AppFunctionDataTypeMetadataDocument(
298                 type = AppFunctionDataTypeMetadata.TYPE_OBJECT,
299                 properties =
300                     listOf(
301                         AppFunctionNamedDataTypeMetadataDocument(
302                             name = "property1",
303                             dataTypeMetadata =
304                                 AppFunctionDataTypeMetadataDocument(
305                                     type = AppFunctionDataTypeMetadata.TYPE_INT,
306                                     isNullable = false
307                                 )
308                         )
309                     ),
310                 required = listOf("property1"),
311                 objectQualifiedName = "ObjectType",
312                 isNullable = false
313             )
314 
315         val metadata = document.toAppFunctionDataTypeMetadata()
316 
317         assertThat(metadata)
318             .isEqualTo(
319                 AppFunctionObjectTypeMetadata(
320                     properties =
321                         mapOf(
322                             "property1" to
323                                 AppFunctionPrimitiveTypeMetadata(
324                                     type = AppFunctionDataTypeMetadata.TYPE_INT,
325                                     isNullable = false
326                                 )
327                         ),
328                     required = listOf("property1"),
329                     qualifiedName = "ObjectType",
330                     isNullable = false
331                 )
332             )
333     }
334 
335     @Test
336     fun appFunctionDataTypeMetadataDocument_toAppFunctionReferenceTypeMetadata_returnsCorrectMetadata() {
337         val document =
338             AppFunctionDataTypeMetadataDocument(
339                 type = AppFunctionDataTypeMetadata.TYPE_REFERENCE,
340                 dataTypeReference = "someReference",
341                 isNullable = true
342             )
343 
344         val metadata = document.toAppFunctionDataTypeMetadata()
345 
346         assertThat(metadata)
347             .isEqualTo(
348                 AppFunctionReferenceTypeMetadata(
349                     referenceDataType = "someReference",
350                     isNullable = true
351                 )
352             )
353     }
354 
355     @Test
356     fun appFunctionDataTypeMetadataDocument_toAppFunctionAllOfTypeMetadata_returnsCorrectMetadata() {
357         val document =
358             AppFunctionDataTypeMetadataDocument(
359                 type = AppFunctionDataTypeMetadata.TYPE_ALL_OF,
360                 allOf =
361                     listOf(
362                         AppFunctionDataTypeMetadataDocument(
363                             type = AppFunctionDataTypeMetadata.TYPE_INT,
364                             isNullable = false
365                         )
366                     ),
367                 objectQualifiedName = "AllOfType",
368                 isNullable = false
369             )
370 
371         val metadata = document.toAppFunctionDataTypeMetadata()
372 
373         assertThat(metadata)
374             .isEqualTo(
375                 AppFunctionAllOfTypeMetadata(
376                     matchAll =
377                         listOf(
378                             AppFunctionPrimitiveTypeMetadata(
379                                 type = AppFunctionDataTypeMetadata.TYPE_INT,
380                                 isNullable = false
381                             )
382                         ),
383                     qualifiedName = "AllOfType",
384                     isNullable = false
385                 )
386             )
387     }
388 }
389