Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ android {
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.13"
kotlinCompilerExtensionVersion = "1.5.14"
}

publishing {
Expand Down Expand Up @@ -67,7 +67,7 @@ publishing {
}
groupId = "sergio.sastre.composable.preview.scanner"
artifactId = "android"
version = "0.3.0"
version = "0.3.1"
}
}
}
5 changes: 3 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
plugins {
alias(libs.plugins.android.application) version "8.4.2" apply false
alias(libs.plugins.android.library) version "8.4.2" apply false
alias(libs.plugins.jetbrains.kotlin.android) version "1.9.23" apply false
alias(libs.plugins.jetbrains.kotlin.jvm) version "1.9.23" apply false
alias(libs.plugins.jetbrains.kotlin.android) version "1.9.24" apply false
alias(libs.plugins.jetbrains.kotlin.jvm) version "1.9.24" apply false
alias(libs.plugins.jetbrains.compose) version "1.6.11" apply false
alias(libs.plugins.roborazzi) version "1.22.0" apply false
alias(libs.plugins.paparazzi) version "1.3.4" apply false
}
4 changes: 2 additions & 2 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.9.23"
kotlin("jvm") version "1.9.24"
id("org.jetbrains.compose") // required to resolve compose runtime
id("maven-publish")
}
Expand All @@ -24,7 +24,7 @@ publishing {
}
groupId = "sergio.sastre.composable.preview.scanner"
artifactId = "core"
version = "0.3.0"
version = "0.3.1"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,42 @@ class ComposablesWithPreviewsFinder<T>(
private val previewInfoMapper: ComposablePreviewInfoMapper<T>,
private val previewMapperCreator: ComposablePreviewMapperCreator<T>,
) {
private val classLoader = this::class.java.classLoader

fun findFor(
classInfo: ClassInfo,
scanResultFilterState: ScanResultFilterState<T>,
): List<ComposablePreview<T>> =
classInfo.declaredMethodInfo.asSequence().flatMap { methodInfo ->
// evaluate if method has preview
): List<ComposablePreview<T>> {
val clazz = Class.forName(classInfo.name, false, classLoader)

return classInfo.declaredMethodInfo.asSequence().flatMap { methodInfo ->
methodInfo.getAnnotationInfo(annotationToScanClassName)?.let {
when (
methodInfo.hasExcludedAnnotation(scanResultFilterState) || scanResultFilterState.excludesMethod(methodInfo)
) {
false ->
methodInfo.toSequenceOfMethods().flatMap { method ->
if (methodInfo.hasExcludedAnnotation(scanResultFilterState) || scanResultFilterState.excludesMethod(methodInfo)) {
emptySequence()
} else {
val methods = if (methodInfo.isPrivate) clazz.declaredMethods else clazz.methods

methods.asSequence()
.filter { it.name == methodInfo.name }
.onEach {
if (methodInfo.isPrivate) {
it.isAccessible = true
}
}
.flatMap { method ->
method.repeatMethodPerPreviewAnnotation(
methodInfo,
scanResultFilterState
)
}

true -> emptySequence()
}
} ?: emptySequence()
}
.toSet()
.flatMap { mapper ->
mapper.mapToComposablePreviews()
}
}

private fun ScanResultFilterState<T>.excludesMethod(methodInfo: MethodInfo): Boolean =
!includesPrivatePreviews && methodInfo.isPrivate
Expand All @@ -60,25 +70,6 @@ class ComposablesWithPreviewsFinder<T>(
false -> false
}

private fun MethodInfo.toSequenceOfMethods(): Sequence<Method> =
when (isPrivate) {
true -> Class.forName(className)
.declaredMethods
.asSequence()
.filter {
it.name.substringAfterLast(".") == name
}.also { methods ->
methods.forEach { it.isAccessible = true }
}

false -> Class.forName(className)
.methods
.asSequence()
.filter {
it.name.substringAfterLast(".") == name
}
}

private fun Method.repeatMethodPerPreviewAnnotation(
methodInfo: MethodInfo,
scanResultFilterState: ScanResultFilterState<T>,
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
android.enableJetifier=true
android.jetifier.ignorelist=android-base-common,common
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
Expand Down
9 changes: 6 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ material = "1.11.0"
composeBom = "2024.04.01"
composeRuntime = "1.6.6"
jetbrainsCompose = "1.6.11"
kotlin = "1.9.23"
kotlinReflect = "1.9.23"
jetbrainsKotlinJvm = "1.9.23"
kotlin = "1.9.24"
kotlinReflect = "1.9.24"
jetbrainsKotlinJvm = "1.9.24"
robolectric = "4.13"
roborazzi = "1.22.0"
roborazziCompose = "1.22.0"
paparazzi = "1.3.4"
testParameterInjector = "1.16"

[libraries]
Expand All @@ -34,6 +35,7 @@ material = { group = "com.google.android.material", name = "material", version.r
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref = "roborazzi" }
roborazzi-compose = { module = "io.github.takahirom.roborazzi:roborazzi-compose", version.ref = "roborazziCompose" }
paparazzi = { module = "app.cash.paparazzi:paparazzi", version.ref = "paparazzi"}
test-parameter-injector = { module = "com.google.testparameterinjector:test-parameter-injector", version.ref = "testParameterInjector" }

[plugins]
Expand All @@ -43,3 +45,4 @@ jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref =
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }
jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "jetbrainsCompose" }
roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" }
paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi" }
4 changes: 2 additions & 2 deletions jvm/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.9.23"
kotlin("jvm") version "1.9.24"
id("maven-publish")
}

Expand All @@ -22,7 +22,7 @@ publishing {
}
groupId = "sergio.sastre.composable.preview.scanner"
artifactId = "jvm"
version = "0.3.0"
version = "0.3.1"
}
}
}
12 changes: 10 additions & 2 deletions tests/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.roborazzi)
}

// Apply conditionally via CLI to avoid plugin clashes
if (project.hasProperty("library")) {
when (project.property("library")) {
"roborazzi" -> apply(plugin = "io.github.takahirom.roborazzi")
"paparazzi" -> apply(plugin = "app.cash.paparazzi")
}
}

android {
Expand Down Expand Up @@ -34,7 +41,7 @@ android {
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.13"
kotlinCompilerExtensionVersion = "1.5.14"
}

compileOptions {
Expand Down Expand Up @@ -74,6 +81,7 @@ dependencies {
testImplementation(libs.roborazzi.compose)
testImplementation(libs.roborazzi)
testImplementation(libs.robolectric)
testImplementation(libs.paparazzi)

androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.test.runner)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package sergio.sastre.composable.preview.scanner.androidvals

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

// This was added to reproduce #27 when running Paparazzi tests
// https://github.com/sergio-sastre/ComposablePreviewScanner/issues/27

val androidVal = android.graphics.Path()
private val privateAndroidVal = android.graphics.Path()

@Composable
fun Example(){
androidVal
Text("Example")
}

@Composable
fun Example2(){
privateAndroidVal
Text("Example 2")
}

@Preview
@Composable
fun ExamplePreview(){
Example()
}


@Preview
@Composable
fun Example2Preview(){
Example2()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package sergio.sastre.composable.preview.scanner.tests.screenshots

import app.cash.paparazzi.Paparazzi
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import sergio.sastre.composable.preview.scanner.android.AndroidComposablePreviewScanner
import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview

/**
* These tests ensure that the invoke() function of a ComposablePreview works as expected
* for all the @Composable's in the main source.
*
* ./gradlew :tests:recordPaparazziDebug --tests 'PaparazziComposablePreviewInvokeTests' -Plibrary=paparazzi
*/
@RunWith(Parameterized::class)
class PaparazziComposablePreviewInvokeTests(
private val preview: ComposablePreview<AndroidPreviewInfo>,
) {

companion object {
private val cachedPreviews: List<ComposablePreview<AndroidPreviewInfo>> by lazy {
AndroidComposablePreviewScanner()
.scanPackageTrees("sergio.sastre.composable.preview.scanner")
.includePrivatePreviews()
.getPreviews()
}

@JvmStatic
@Parameterized.Parameters
fun values(): List<ComposablePreview<AndroidPreviewInfo>> = cachedPreviews
}

@get:Rule
val paparazzi = Paparazzi()

@Test
fun snapshot() {
paparazzi.snapshot {
preview()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview
* These tests ensure that the invoke() function of a ComposablePreview works as expected
* for all the @Composable's in the main source.
*
* ./gradlew :tests:recordRoborazziDebug --test '*PreviewInvokeTests'
* ./gradlew :tests:recordRoborazziDebug --tests 'RoborazziComposablePreviewInvokeTests' -Plibrary=roborazzi
*/

@RunWith(ParameterizedRobolectricTestRunner::class)
class ComposablePreviewInvokeTests(
class RoborazziComposablePreviewInvokeTests(
private val preview: ComposablePreview<AndroidPreviewInfo>,
) {

Expand Down