1 /* 2 * Copyright (C) 2021 Square, Inc. 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 * https://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 package com.squareup.kotlinpoet.javapoet 17 18 import com.google.common.truth.Truth.assertThat 19 import com.squareup.javapoet.ArrayTypeName 20 import com.squareup.kotlinpoet.ANY 21 import com.squareup.kotlinpoet.ARRAY 22 import com.squareup.kotlinpoet.BOOLEAN 23 import com.squareup.kotlinpoet.BYTE 24 import com.squareup.kotlinpoet.CHAR 25 import com.squareup.kotlinpoet.DOUBLE 26 import com.squareup.kotlinpoet.ENUM 27 import com.squareup.kotlinpoet.FLOAT 28 import com.squareup.kotlinpoet.INT 29 import com.squareup.kotlinpoet.INT_ARRAY 30 import com.squareup.kotlinpoet.LIST 31 import com.squareup.kotlinpoet.LONG 32 import com.squareup.kotlinpoet.MAP 33 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy 34 import com.squareup.kotlinpoet.SET 35 import com.squareup.kotlinpoet.SHORT 36 import com.squareup.kotlinpoet.STAR 37 import com.squareup.kotlinpoet.STRING 38 import com.squareup.kotlinpoet.U_BYTE 39 import com.squareup.kotlinpoet.U_INT 40 import com.squareup.kotlinpoet.U_LONG 41 import com.squareup.kotlinpoet.U_SHORT 42 import com.squareup.kotlinpoet.asClassName 43 import com.squareup.kotlinpoet.typeNameOf 44 import org.junit.Test 45 46 @OptIn(KotlinPoetJavaPoetPreview::class) 47 class PoetInteropTest { 48 49 @Test classNamesMatchnull50 fun classNamesMatch() { 51 val kotlinPoetCN = PoetInteropTest::class.asClassName() 52 val javapoetCN = kotlinPoetCN.toJClassName() 53 54 assertThat(javapoetCN.toKTypeName()).isEqualTo(kotlinPoetCN) 55 assertThat(JClassName.get(PoetInteropTest::class.java)).isEqualTo(javapoetCN) 56 } 57 58 @Test nestedClassNamesMatchnull59 fun nestedClassNamesMatch() { 60 val kotlinPoetCN = PoetInteropTest::class.asClassName().nestedClass("Foo").nestedClass("Bar") 61 val javapoetCN = kotlinPoetCN.toJClassName() 62 63 assertThat(javapoetCN.toKTypeName()).isEqualTo(kotlinPoetCN) 64 assertThat(JClassName.get(PoetInteropTest::class.java).nestedClass("Foo").nestedClass("Bar")) 65 .isEqualTo(javapoetCN) 66 } 67 68 @Test kotlinIntrinsicsMapCorrectlyToJavanull69 fun kotlinIntrinsicsMapCorrectlyToJava() { 70 // To Java 71 assertThat(LIST.toJTypeName()).isEqualTo(PoetInterop.CN_JAVA_LIST) 72 assertThat(SET.toJTypeName()).isEqualTo(PoetInterop.CN_JAVA_SET) 73 assertThat(MAP.toJTypeName()).isEqualTo(PoetInterop.CN_JAVA_MAP) 74 assertThat(STRING.toJTypeName()).isEqualTo(PoetInterop.CN_JAVA_STRING) 75 assertThat(ANY.toJTypeName()).isEqualTo(JTypeName.OBJECT) 76 77 // To Kotlin 78 assertThat(PoetInterop.CN_JAVA_LIST.toKTypeName()).isEqualTo(LIST) 79 assertThat(PoetInterop.CN_JAVA_SET.toKTypeName()).isEqualTo(SET) 80 assertThat(PoetInterop.CN_JAVA_MAP.toKTypeName()).isEqualTo(MAP) 81 assertThat(PoetInterop.CN_JAVA_STRING.toKTypeName()).isEqualTo(STRING) 82 assertThat(JTypeName.OBJECT.toKTypeName()).isEqualTo(ANY) 83 } 84 85 @Test boxIfPrimitiveRequestReturnsBoxedPrimitivenull86 fun boxIfPrimitiveRequestReturnsBoxedPrimitive() { 87 assertThat(BOOLEAN.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.BOOLEAN.box()) 88 assertThat(BYTE.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.BYTE.box()) 89 assertThat(CHAR.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.CHAR.box()) 90 assertThat(SHORT.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.SHORT.box()) 91 assertThat(INT.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.INT.box()) 92 assertThat(LONG.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.LONG.box()) 93 assertThat(FLOAT.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.FLOAT.box()) 94 assertThat(DOUBLE.toJTypeName(boxIfPrimitive = true)).isEqualTo(JTypeName.DOUBLE.box()) 95 } 96 97 @Test primitivesAreUnboxedByDefaultnull98 fun primitivesAreUnboxedByDefault() { 99 assertThat(BOOLEAN.toJTypeName()).isEqualTo(JTypeName.BOOLEAN) 100 assertThat(BYTE.toJTypeName()).isEqualTo(JTypeName.BYTE) 101 assertThat(CHAR.toJTypeName()).isEqualTo(JTypeName.CHAR) 102 assertThat(SHORT.toJTypeName()).isEqualTo(JTypeName.SHORT) 103 assertThat(INT.toJTypeName()).isEqualTo(JTypeName.INT) 104 assertThat(LONG.toJTypeName()).isEqualTo(JTypeName.LONG) 105 assertThat(FLOAT.toJTypeName()).isEqualTo(JTypeName.FLOAT) 106 assertThat(DOUBLE.toJTypeName()).isEqualTo(JTypeName.DOUBLE) 107 } 108 109 @Test nullablePrimitiveBoxedByDefaultnull110 fun nullablePrimitiveBoxedByDefault() { 111 assertThat(BOOLEAN.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.BOOLEAN.box()) 112 assertThat(BYTE.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.BYTE.box()) 113 assertThat(CHAR.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.CHAR.box()) 114 assertThat(SHORT.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.SHORT.box()) 115 assertThat(INT.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.INT.box()) 116 assertThat(LONG.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.LONG.box()) 117 assertThat(FLOAT.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.FLOAT.box()) 118 assertThat(DOUBLE.copy(nullable = true).toJTypeName()).isEqualTo(JTypeName.DOUBLE.box()) 119 } 120 121 @Test arrayTypesConversionnull122 fun arrayTypesConversion() { 123 assertThat(ARRAY.parameterizedBy(INT).toJParameterizedOrArrayTypeName()) 124 .isEqualTo(ArrayTypeName.of(JTypeName.INT)) 125 assertThat(ARRAY.parameterizedBy(INT.copy(nullable = true)).toJParameterizedOrArrayTypeName()) 126 .isEqualTo(ArrayTypeName.of(JTypeName.INT.box())) 127 assertThat(ArrayTypeName.of(JTypeName.INT).toKTypeName()).isEqualTo(INT_ARRAY) 128 assertThat(ArrayTypeName.of(JTypeName.INT.box()).toKTypeName()) 129 .isEqualTo(ARRAY.parameterizedBy(INT)) 130 } 131 132 class GenericType<T> 133 134 @Test wildcardsnull135 fun wildcards() { 136 val inKType = typeNameOf<GenericType<in String>>() 137 val superJType = JParameterizedTypeName.get( 138 JClassName.get(GenericType::class.java), 139 JWildcardTypeName.supertypeOf(String::class.java), 140 ) 141 assertThat(inKType.toJTypeName()).isEqualTo(superJType) 142 assertThat(superJType.toKTypeName().toString()).isEqualTo(inKType.toString()) 143 144 val outKType = typeNameOf<GenericType<out String>>() 145 val extendsJType = JParameterizedTypeName.get( 146 JClassName.get(GenericType::class.java), 147 JWildcardTypeName.subtypeOf(String::class.java), 148 ) 149 assertThat(outKType.toJTypeName()).isEqualTo(extendsJType) 150 assertThat(extendsJType.toKTypeName().toString()).isEqualTo(outKType.toString()) 151 152 val star = typeNameOf<GenericType<*>>() 153 val extendsObjectJType = JParameterizedTypeName.get( 154 JClassName.get(GenericType::class.java), 155 JWildcardTypeName.subtypeOf(JTypeName.OBJECT), 156 ) 157 assertThat(star.toJTypeName()).isEqualTo(extendsObjectJType) 158 assertThat(extendsObjectJType.toKTypeName().toString()).isEqualTo(star.toString()) 159 assertThat(STAR.toJTypeName()).isEqualTo(JWildcardTypeName.subtypeOf(JTypeName.OBJECT)) 160 assertThat(JWildcardTypeName.subtypeOf(JTypeName.OBJECT).toKTypeName()).isEqualTo(STAR) 161 } 162 163 @Test complexnull164 fun complex() { 165 val complexType = typeNameOf<Map<String?, List<MutableMap<Int, IntArray>>>>() 166 val jType = JParameterizedTypeName.get( 167 JClassName.get(Map::class.java), 168 JClassName.get(String::class.java), 169 JParameterizedTypeName.get( 170 JClassName.get(List::class.java), 171 JParameterizedTypeName.get( 172 JClassName.get(Map::class.java), 173 JClassName.INT.box(), 174 ArrayTypeName.of(JClassName.INT), 175 ), 176 ), 177 ) 178 assertThat(complexType.toJTypeName()).isEqualTo(jType) 179 180 assertThat(jType.toKTypeName()) 181 .isEqualTo(typeNameOf<Map<String, List<MutableMap<Int, IntArray>>>>()) 182 } 183 184 @Test uTypesAreJustNormalTypesInJavanull185 fun uTypesAreJustNormalTypesInJava() { 186 assertThat(U_BYTE.toJTypeName()).isEqualTo(JTypeName.BYTE) 187 assertThat(U_SHORT.toJTypeName()).isEqualTo(JTypeName.SHORT) 188 assertThat(U_INT.toJTypeName()).isEqualTo(JTypeName.INT) 189 assertThat(U_LONG.toJTypeName()).isEqualTo(JTypeName.LONG) 190 } 191 192 @Test enumsnull193 fun enums() { 194 assertThat(ENUM.toJTypeName()).isEqualTo(PoetInterop.CN_JAVA_ENUM) 195 assertThat(PoetInterop.CN_JAVA_ENUM.toKTypeName()).isEqualTo(ENUM) 196 } 197 } 198