1 /* 2 * Copyright (C) 2024 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.typeitem 18 19 import com.android.tools.metalava.model.testsuite.BaseModelTest 20 import com.android.tools.metalava.testing.java 21 import com.android.tools.metalava.testing.kotlin 22 import com.google.common.truth.Truth.assertThat 23 import org.junit.Test 24 import org.junit.runners.Parameterized 25 26 class CommonIsAssignableFromTest : BaseModelTest() { 27 28 data class Comparison( 29 val field1: String, 30 val field2: String, 31 val expectedResult: Boolean, 32 ) { toStringnull33 override fun toString(): String { 34 return "$field1 to $field2" 35 } 36 } 37 38 companion object { 39 private val comparisons = 40 listOf( 41 Comparison("string", "string", true), 42 Comparison("obj", "string", true), 43 Comparison("string", "obj", false), 44 Comparison("primitiveInt", "number", false), 45 Comparison("number", "primitiveInt", true), 46 Comparison("boxedInt", "primitiveInt", true), 47 Comparison("primitiveInt", "boxedInt", false), 48 Comparison("number", "boxedInt", true), 49 Comparison("boxedInt", "number", false), 50 Comparison("listOfInt", "listOfInt", true), 51 Comparison("listOfInt", "listOfNumber", false), 52 Comparison("listOfNumber", "listOfInt", false), 53 Comparison("mapOfNumberToString", "mapOfNumberToString", true), 54 Comparison("mapOfNumberToString", "mapOfIntToString", false), 55 Comparison("mapOfIntToString", "mapOfNumberToString", false), 56 ) 57 comparisonsnull58 @JvmStatic @Parameterized.Parameters fun comparisons() = comparisons 59 } 60 61 /** 62 * Set by injection by [Parameterized] after class initializers are called. 63 * 64 * Anything that accesses this, either directly or indirectly must do it after initialization, 65 * e.g. from lazy fields or in methods called from test methods. 66 * 67 * See [codebaseCreatorConfig] for more info. 68 */ 69 @Parameterized.Parameter(0) lateinit var comparison: Comparison 70 71 @Test 72 fun `Test assignability without unboxing`() { 73 74 runCodebaseTest( 75 java( 76 """ 77 package test.foo; 78 import java.util.*; 79 public class Subject { 80 public Object obj; 81 public String string; 82 public int primitiveInt; 83 public Number number; 84 public Integer boxedInt; 85 public List<Integer> listOfInt; 86 public List<Number> listOfNumber; 87 public Map<Integer, String> mapOfIntToString; 88 public Map<Number, String> mapOfNumberToString; 89 } 90 """ 91 ), 92 kotlin( 93 """ 94 package test.foo 95 class Subject { 96 @JvmField 97 var obj: Any? = null 98 @JvmField 99 var string: String? = null 100 @JvmField 101 var primitiveInt = 0 102 @JvmField 103 var number: Number? = null 104 @JvmField 105 var boxedInt: Int? = null 106 @JvmField 107 var listOfInt: MutableList<Int>? = null 108 @JvmField 109 var listOfNumber: MutableList<Number>? = null 110 @JvmField 111 var mapOfIntToString: MutableMap<Int, String>? = null 112 @JvmField 113 var mapOfNumberToString: MutableMap<Number, String>? = null 114 } 115 """ 116 ), 117 signature( 118 """ 119 // Signature format: 3.0 120 package test.foo { 121 public class Subject { 122 field public Object obj; 123 field public String string; 124 field public int primitiveInt; 125 field public Number number; 126 field public Integer boxedInt; 127 field public java.util.List<Integer> listOfInt; 128 field public java.util.List<Number> listOfNumber; 129 field public java.util.Map<Integer, String> mapOfIntToString; 130 field public java.util.Map<Number, String> mapOfNumberToString; 131 } 132 } 133 """ 134 ), 135 ) { 136 val subject = codebase.assertClass("test.foo.Subject") 137 138 val field1Type = subject.assertField(comparison.field1).type() 139 val field2Type = subject.assertField(comparison.field2).type() 140 141 assertThat(field1Type.isAssignableFromWithoutUnboxing(field2Type)) 142 .isEqualTo(comparison.expectedResult) 143 } 144 } 145 } 146