Skip to content

Commit

Permalink
Add unit tests for ksp processor
Browse files Browse the repository at this point in the history
  • Loading branch information
geoff-powell committed Sep 3, 2024
1 parent 4091882 commit 72896c1
Show file tree
Hide file tree
Showing 8 changed files with 503 additions and 34 deletions.
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ compose = "1.6.8"
coroutines = "1.8.1"
javaTarget = "11"
kotlin = "2.0.20"
kotlinCompileTesting = "1.5.0"
kotlinPoet = "1.18.1"
ksp = "2.0.20-1.0.24"
layoutlib = "14.0.9"
Expand All @@ -32,6 +33,8 @@ guava = { module = "com.google.guava:guava", version = "33.3.0-jre" }
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinPoet" }
kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlinPoet" }
kotlin-compile-testing = { module = "com.github.tschuchortdev:kotlin-compile-testing", version.ref = "kotlinCompileTesting" }
kotlin-compile-testing-ksp = { module = "com.github.tschuchortdev:kotlin-compile-testing-ksp", version.ref = "kotlinCompileTesting" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }

Expand Down
5 changes: 5 additions & 0 deletions paparazzi-preview-processor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ dependencies {
implementation libs.kotlinpoet
implementation libs.kotlinpoet.ksp
implementation libs.ksp

testImplementation libs.junit
testImplementation libs.truth
testImplementation libs.kotlin.compile.testing
testImplementation libs.kotlin.compile.testing.ksp
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.buildCodeBlock

internal object PaparazziPoet {

fun buildFiles(
functions: Sequence<KSFunctionDeclaration>,
isTest: Boolean,
Expand Down Expand Up @@ -50,15 +49,13 @@ internal object PaparazziPoet {

when {
visibilityCheck.isPrivate -> addError(
visibilityCheck = visibilityCheck,
function = func,
snapshotName = snapshotName,
buildErrorMessage = {
"$it is private. Make it internal or public to generate a snapshot."
}
)
previewParam != null -> addError(
visibilityCheck = visibilityCheck,
function = func,
snapshotName = snapshotName,
buildErrorMessage = {
Expand Down Expand Up @@ -87,24 +84,21 @@ internal object PaparazziPoet {
block: (KSFunctionDeclaration, KSValueParameter?) -> Unit
) =
flatMap { func ->
val previewParam = func.previewParam()
func.findDistinctPreviews()
val previewParam = func.parameters.firstOrNull { param ->
param.annotations.any { it.isPreviewParameter() }
}
func.annotations.findPreviews().distinct()
.map { Pair(func, previewParam) }
}.forEach { (func, previewParam) ->
block(func, previewParam)
}

private fun CodeBlock.Builder.addError(
visibilityCheck: VisibilityCheck,
function: KSFunctionDeclaration,
snapshotName: String,
buildErrorMessage: (String?) -> String
) {
val qualifiedName = if (visibilityCheck.isFunctionPrivate) {
function.qualifiedName?.asString()
} else {
null
}
val qualifiedName = function.qualifiedName?.asString()

addStatement("%L.PaparazziPreviewData.Error(", PACKAGE_NAME)
indent()
Expand All @@ -114,18 +108,6 @@ internal object PaparazziPoet {
addStatement("),")
}

private fun CodeBlock.Builder.addProvider(
function: KSFunctionDeclaration,
snapshotName: String
) {
addStatement("%L.PaparazziPreviewData.Provider(", PACKAGE_NAME)
indent()
addStatement("snapshotName = %S,", snapshotName)
addStatement("composable = { %L(it) },", function.qualifiedName?.asString())
unindent()
addStatement("),")
}

private fun CodeBlock.Builder.addDefault(
function: KSFunctionDeclaration,
snapshotName: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ public class PreviewProcessor(
private val environment: SymbolProcessorEnvironment
) : SymbolProcessor {

private var invoked = false

override fun process(resolver: Resolver): List<KSAnnotated> {
if (invoked) return emptyList()
invoked = true
// Due to codgen and multi-round processing of ksp
// https://kotlinlang.org/docs/ksp-multi-round.html
if (resolver.getNewFiles().any { it.fileName.contains("PaparazziPreviews.kt") }) {
"Skipping subsequent run due to PaparazziPreviews.kt already created and caused ksp re-run".log()
return emptyList()
}

val allFiles = resolver.getAllFiles().toList()
if (allFiles.isEmpty()) return emptyList()
Expand All @@ -41,7 +43,7 @@ public class PreviewProcessor(
.also { functions ->
"found ${functions.count()} function(s)".log()
PaparazziPoet.buildFiles(functions, isTestSourceSet, env).forEach { file ->
"writing file: ${file.packageName}.${file.name}".log()
"writing file: ${file.packageName}.${file.name}.kt".log()
file.writeTo(environment.codeGenerator, dependencies)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ internal fun Sequence<KSAnnotation>.findPreviews(stack: Set<KSAnnotation> = setO
return direct.plus(indirect)
}

internal fun KSFunctionDeclaration.findDistinctPreviews() = annotations.findPreviews().distinct()

internal fun KSFunctionDeclaration.previewParam() = parameters.firstOrNull { param ->
param.annotations.any { it.isPreviewParameter() }
}

internal data class EnvironmentOptions(
val namespace: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.cash.paparazzi.preview.processor

import com.tschuchort.compiletesting.KotlinCompilation
import java.io.File

data class KspCompileResult(
val result: KotlinCompilation.Result,
val generatedFiles: List<File>
)
Loading

0 comments on commit 72896c1

Please sign in to comment.