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.documentation 18 19 import com.android.tools.metalava.model.ItemDocumentation 20 import com.android.tools.metalava.model.provider.InputFormat 21 import com.android.tools.metalava.model.testsuite.BaseModelTest 22 import com.android.tools.metalava.testing.java 23 import com.android.tools.metalava.testing.kotlin 24 import java.util.EnumSet 25 import kotlin.test.assertEquals 26 import org.junit.Rule 27 import org.junit.Test 28 import org.junit.rules.TestRule 29 import org.junit.runner.Description 30 import org.junit.runners.Parameterized 31 import org.junit.runners.model.Statement 32 33 /** Common tests for implementations of [ItemDocumentation] */ 34 class CommonParameterizedDocumentationTest : BaseModelTest() { 35 36 @Parameterized.Parameter(0) lateinit var params: TestParams 37 38 data class TestParams( 39 val name: String, 40 val inputFormats: Set<InputFormat> = EnumSet.allOf(InputFormat::class.java), 41 val imports: List<String> = emptyList(), 42 val comment: String, 43 val expectedText: String = comment, 44 val expectedFullyQualified: String = expectedText, 45 ) { skipForInputFormatnull46 fun skipForInputFormat(inputFormat: InputFormat?) = inputFormat !in inputFormats 47 48 override fun toString(): String { 49 return name 50 } 51 } 52 53 companion object { 54 private val javaOnly = EnumSet.of(InputFormat.JAVA) 55 private val kotlinOnly = EnumSet.of(InputFormat.KOTLIN) 56 57 private val params = 58 listOf( 59 TestParams( 60 name = "inline comment", 61 comment = "// inline comment", 62 expectedText = "", 63 ), 64 TestParams( 65 name = "inline comment - link tag", 66 comment = "// inline comment - {@link}", 67 expectedText = "", 68 ), 69 TestParams( 70 name = "block comment", 71 comment = "/* block comment */", 72 expectedText = "", 73 ), 74 TestParams( 75 name = "block comment - link tag", 76 comment = "/* block comment - {@link} */", 77 expectedText = "", 78 ), 79 TestParams( 80 name = "doc comment - plain text", 81 comment = "/** doc comment */", 82 ), 83 TestParams( 84 name = "doc comment with link - java", 85 inputFormats = javaOnly, 86 imports = listOf("java.util.List"), 87 comment = "/** {@link List} */", 88 expectedFullyQualified = "/** {@link java.util.List List} */", 89 ), 90 TestParams( 91 name = "doc comment with link - kotlin", 92 inputFormats = kotlinOnly, 93 imports = listOf("kotlin.random.Random"), 94 comment = "/** {@link Random} */", 95 // Doc comments in Kotlin are not fully qualified as that is only needed for 96 // java stubs due to an issue with doclava. Kotlin stubs are not supported. 97 ), 98 ) 99 paramsnull100 @JvmStatic @Parameterized.Parameters fun params() = params 101 } 102 103 /** 104 * [TestRule] that ignores tests whose [TestParams] are not suitable for the current 105 * [inputFormat]. 106 */ 107 @get:Rule 108 val filter = 109 object : TestRule { 110 override fun apply(base: Statement, description: Description): Statement { 111 return object : Statement() { 112 override fun evaluate() { 113 if (params.skipForInputFormat(inputFormat)) return 114 base.evaluate() 115 } 116 } 117 } 118 } 119 importsnull120 private fun imports(): String = 121 if (params.imports.isEmpty()) "" 122 else { 123 val terminator = if (inputFormat == InputFormat.JAVA) ";" else "\n" 124 params.imports.joinToString { " import $it$terminator" } 125 } 126 127 @Test Documentation textnull128 fun `Documentation text`() { 129 runSourceCodebaseTest( 130 java( 131 """ 132 package test.pkg; 133 ${imports()} 134 ${params.comment} 135 public class Test { 136 } 137 """ 138 ), 139 kotlin( 140 """ 141 package test.pkg 142 ${imports()} 143 144 ${params.comment} 145 class Test 146 """ 147 ) 148 ) { 149 val testClass = codebase.assertClass("test.pkg.Test") 150 val documentation = testClass.documentation 151 152 assertEquals(params.expectedText, documentation.text) 153 } 154 } 155 156 @Test Documentation fully qualifiednull157 fun `Documentation fully qualified`() { 158 runSourceCodebaseTest( 159 java( 160 """ 161 package test.pkg; 162 ${imports()} 163 164 ${params.comment} 165 public class Test { 166 } 167 """ 168 ), 169 kotlin( 170 """ 171 package test.pkg 172 ${imports()} 173 174 ${params.comment} 175 class Test 176 """ 177 ) 178 ) { 179 val testClass = codebase.assertClass("test.pkg.Test") 180 val documentation = testClass.documentation 181 182 assertEquals(params.expectedFullyQualified, documentation.fullyQualifiedDocumentation()) 183 } 184 } 185 } 186