-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Custom exclusion annotation works for a plain @Preview
but fails when the preview wraps content in an annotated theme function.
Reproducer: fresh clone of repo https://github.com/jacoco/example-jacoco-kotlin-compose Command: ./gradlew clean test jacocoTestReport
Snippet:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
annotation class ExcludeFromJacocoGeneratedReport
package org.example
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
@Composable
fun example() {
var counter by remember { mutableStateOf(0) }
if (counter == 2) {
return
}
Button(onClick = { counter++ }) {
if (counter == 0) {
Text("Click me")
} else {
Text("Click me again")
}
}
}
@Composable
@ExcludeFromJacocoGeneratedReport
fun DummyTheme(content: @Composable () -> Unit) {
content()
}
@Preview
@Composable
@ExcludeFromJacocoGeneratedReport
fun NoThemePreview() {
example()
}
@Preview
@Composable
@ExcludeFromJacocoGeneratedReport
fun ThemedPreview() {
DummyTheme @ExcludeFromJacocoGeneratedReport {
example()
}
}
Expected: Both previews fully excluded.
Actual: NoThemePreview excluded, ThemedPreview counted (lines attributed to generated synthetic methods).
Question:
- Is this an expected limitation of how the Compose compiler rewrites
@Composable
/@Preview
functions? - What is the recommended JaCoCo filter (class/method name patterns or annotations) to exclude every
@Preview
function and any helper lambdas they generate?
===========
Generated jacocoTestReport.xml
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd">
<report name="example-jacoco-kotlin-compose">
<sessioninfo id="Tomass-MacBook-Pro-3.local-6e2358ea" start="1760083990908" dump="1760083992584"/>
<package name="org/example">
<class name="org/example/ExampleKt" sourcefilename="Example.kt">
<method name="example" desc="(Landroidx/compose/runtime/Composer;I)V" line="9">
<counter type="INSTRUCTION" missed="0" covered="74"/>
<counter type="BRANCH" missed="0" covered="2"/>
<counter type="LINE" missed="0" covered="6"/>
<counter type="COMPLEXITY" missed="0" covered="2"/>
<counter type="METHOD" missed="0" covered="1"/>
</method>
<method name="example$lambda$1" desc="(Landroidx/compose/runtime/MutableState;)I" line="10">
<counter type="INSTRUCTION" missed="0" covered="10"/>
<counter type="LINE" missed="0" covered="1"/>
<counter type="COMPLEXITY" missed="0" covered="1"/>
<counter type="METHOD" missed="0" covered="1"/>
</method>
<method name="example$lambda$2" desc="(Landroidx/compose/runtime/MutableState;I)V" line="10">
<counter type="INSTRUCTION" missed="0" covered="12"/>
<counter type="LINE" missed="0" covered="1"/>
<counter type="COMPLEXITY" missed="0" covered="1"/>
<counter type="METHOD" missed="0" covered="1"/>
</method>
<method name="example$lambda$4$0" desc="(Landroidx/compose/runtime/MutableState;)Lkotlin/Unit;" line="14">
<counter type="INSTRUCTION" missed="0" covered="10"/>
<counter type="LINE" missed="0" covered="1"/>
<counter type="COMPLEXITY" missed="0" covered="1"/>
<counter type="METHOD" missed="0" covered="1"/>
</method>
<method name="example$lambda$5" desc="(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/layout/RowScope;Landroidx/compose/runtime/Composer;I)Lkotlin/Unit;" line="15">
<counter type="INSTRUCTION" missed="0" covered="67"/>
<counter type="BRANCH" missed="0" covered="2"/>
<counter type="LINE" missed="0" covered="5"/>
<counter type="COMPLEXITY" missed="0" covered="2"/>
<counter type="METHOD" missed="0" covered="1"/>
</method>
<counter type="INSTRUCTION" missed="0" covered="173"/>
<counter type="BRANCH" missed="0" covered="4"/>
<counter type="LINE" missed="0" covered="11"/>
<counter type="COMPLEXITY" missed="0" covered="7"/>
<counter type="METHOD" missed="0" covered="5"/>
<counter type="CLASS" missed="0" covered="1"/>
</class>
<class name="org/example/ComposableSingletons$ExampleKt$lambda$-545336751$1" sourcefilename="Example.kt"/>
<class name="org/example/ExcludeFromJacocoGeneratedReport" sourcefilename="ExcludeFromJacocoGeneratedReport.kt"/>
<class name="org/example/ComposableSingletons$ExampleKt" sourcefilename="Example.kt">
<method name="<clinit>" desc="()V" line="42">
<counter type="INSTRUCTION" missed="7" covered="0"/>
<counter type="LINE" missed="1" covered="0"/>
<counter type="COMPLEXITY" missed="1" covered="0"/>
<counter type="METHOD" missed="1" covered="0"/>
</method>
<counter type="INSTRUCTION" missed="7" covered="0"/>
<counter type="LINE" missed="1" covered="0"/>
<counter type="COMPLEXITY" missed="1" covered="0"/>
<counter type="METHOD" missed="1" covered="0"/>
<counter type="CLASS" missed="1" covered="0"/>
</class>
<sourcefile name="Example.kt">
<line nr="9" mi="0" ci="4" mb="0" cb="0"/>
<line nr="10" mi="0" ci="41" mb="0" cb="0"/>
<line nr="11" mi="0" ci="5" mb="0" cb="2"/>
<line nr="12" mi="0" ci="4" mb="0" cb="0"/>
<line nr="14" mi="0" ci="45" mb="0" cb="0"/>
<line nr="15" mi="0" ci="12" mb="0" cb="2"/>
<line nr="16" mi="0" ci="22" mb="0" cb="0"/>
<line nr="17" mi="0" ci="9" mb="0" cb="0"/>
<line nr="18" mi="0" ci="22" mb="0" cb="0"/>
<line nr="20" mi="0" ci="2" mb="0" cb="0"/>
<line nr="22" mi="0" ci="7" mb="0" cb="0"/>
<line nr="42" mi="7" ci="0" mb="0" cb="0"/>
<counter type="INSTRUCTION" missed="7" covered="173"/>
<counter type="BRANCH" missed="0" covered="4"/>
<counter type="LINE" missed="1" covered="11"/>
<counter type="COMPLEXITY" missed="1" covered="7"/>
<counter type="METHOD" missed="1" covered="5"/>
<counter type="CLASS" missed="1" covered="1"/>
</sourcefile>
<sourcefile name="ExcludeFromJacocoGeneratedReport.kt"/>
<counter type="INSTRUCTION" missed="7" covered="173"/>
<counter type="BRANCH" missed="0" covered="4"/>
<counter type="LINE" missed="1" covered="11"/>
<counter type="COMPLEXITY" missed="1" covered="7"/>
<counter type="METHOD" missed="1" covered="5"/>
<counter type="CLASS" missed="1" covered="1"/>
</package>
<counter type="INSTRUCTION" missed="7" covered="173"/>
<counter type="BRANCH" missed="0" covered="4"/>
<counter type="LINE" missed="1" covered="11"/>
<counter type="COMPLEXITY" missed="1" covered="7"/>
<counter type="METHOD" missed="1" covered="5"/>
<counter type="CLASS" missed="1" covered="1"/>
</report>```
Metadata
Metadata
Assignees
Labels
No labels