Skip to content

Commit

Permalink
Fix Jacoco misconfiguration by changing the destination DSL (#347)
Browse files Browse the repository at this point in the history
This includes making a distinction between the report types that output
to a single file (CSV, XML) and those that output to a directory (HTML)
(this is in line with the API provided by the Jacoco plugin itself).

In the process of doing this, fix the integration test of Jacoco which
didn't catch this failure...
  • Loading branch information
mannodermaus authored Aug 11, 2024
1 parent 2645e59 commit 220f5b8
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 146 deletions.
3 changes: 3 additions & 0 deletions plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Change Log

## Unreleased
- JUnit 5.10.3
- Updates to the `jacocoOptions` DSL
- Change the return type of each report type to match Jacoco expectations (html -> Directory; csv & xml -> File)
- Turn off generation of csv & xml reports by default, matching Jacoco default configuration

## 1.10.2.0 (2024-07-25)
- JUnit 5.10.2
Expand Down
22 changes: 16 additions & 6 deletions plugin/android-junit5/api/android-junit5.api
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public final class de/mannodermaus/gradle/plugins/junit5/AndroidJUnitPlatformPlu
}

public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/AndroidJUnitPlatformExtension : groovy/lang/GroovyObjectSupport {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
public fun <init> (Lorg/gradle/api/Project;Lorg/gradle/api/model/ObjectFactory;)V
public final fun configurationParameter (Ljava/lang/String;Ljava/lang/String;)V
public final fun configurationParameters (Ljava/util/Map;)V
public final fun filters (Ljava/lang/String;Lorg/gradle/api/Action;)V
Expand Down Expand Up @@ -40,21 +40,31 @@ public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/InstrumentationT

public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
public final fun getCsv ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report;
public final fun getCsv ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$FileReport;
public abstract fun getExcludedClasses ()Lorg/gradle/api/provider/ListProperty;
public final fun getHtml ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report;
public final fun getHtml ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$DirectoryReport;
public abstract fun getOnlyGenerateTasksForVariants ()Lorg/gradle/api/provider/SetProperty;
public abstract fun getTaskGenerationEnabled ()Lorg/gradle/api/provider/Property;
public final fun getXml ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report;
public final fun getXml ()Lde/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$FileReport;
}

public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report {
public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$DirectoryReport : de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report {
public fun <init> ()V
public abstract fun getDestination ()Lorg/gradle/api/file/DirectoryProperty;
public final fun invoke (Lkotlin/jvm/functions/Function1;)V
}

public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$FileReport : de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report {
public fun <init> ()V
public abstract fun getDestination ()Lorg/gradle/api/file/RegularFileProperty;
public abstract fun getEnabled ()Lorg/gradle/api/provider/Property;
public final fun invoke (Lkotlin/jvm/functions/Function1;)V
}

public abstract class de/mannodermaus/gradle/plugins/junit5/dsl/JacocoOptions$Report {
public abstract fun getDestination ()Lorg/gradle/api/file/FileSystemLocationProperty;
public abstract fun getEnabled ()Lorg/gradle/api/provider/Property;
}

public abstract class de/mannodermaus/gradle/plugins/junit5/tasks/AndroidJUnit5JacocoReport : org/gradle/testing/jacoco/tasks/JacocoReport {
public fun <init> ()V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import java.io.File
import javax.inject.Inject

public abstract class AndroidJUnitPlatformExtension @Inject constructor(
project: Project,
private val objects: ObjectFactory
) : GroovyObjectSupport() {

Expand Down Expand Up @@ -110,18 +111,23 @@ public abstract class AndroidJUnitPlatformExtension @Inject constructor(
/**
* Options for controlling Jacoco reporting
*/
@Suppress("CAST_NEVER_SUCCEEDS")
public val jacocoOptions: JacocoOptions =
objects.newInstance(JacocoOptions::class.java).apply {
taskGenerationEnabled.convention(true)
onlyGenerateTasksForVariants.convention(emptySet())
excludedClasses.set(listOf("**/R.class", "**/R$*.class", "**/BuildConfig.*"))

// Just like Jacoco itself, enable only HTML by default.
// We have to supply an output location for all reports though,
// as keeping this unset would lead to issues
// (ref. https://github.com/mannodermaus/android-junit5/issues/346)
val defaultReportDir = project.layout.buildDirectory.dir("reports/jacoco")
html.enabled.convention(true)
html.destination.set(null as? File)
csv.enabled.convention(true)
csv.destination.set(null as? File)
xml.enabled.convention(true)
xml.destination.set(null as? File)
html.destination.convention(defaultReportDir.map { it.dir("html") })
csv.enabled.convention(false)
csv.destination.convention(defaultReportDir.map { it.file("jacoco.csv") })
xml.enabled.convention(false)
xml.destination.convention(defaultReportDir.map { it.file("jacoco.xml") })
}

public fun jacocoOptions(action: Action<JacocoOptions>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package de.mannodermaus.gradle.plugins.junit5.dsl

import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.file.FileSystemLocationProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.reporting.Report.OutputType
import org.gradle.api.tasks.Input
import org.gradle.internal.enterprise.test.FileProperty
import javax.inject.Inject
Expand Down Expand Up @@ -35,17 +39,17 @@ public abstract class JacocoOptions @Inject constructor(
/**
* Options for controlling the HTML Report generated by Jacoco
*/
public val html: Report = objects.newInstance(Report::class.java)
public val html: DirectoryReport = objects.newInstance(DirectoryReport::class.java)

/**
* Options for controlling the CSV Report generated by Jacoco
*/
public val csv: Report = objects.newInstance(Report::class.java)
public val csv: FileReport = objects.newInstance(FileReport::class.java)

/**
* Options for controlling the XML Report generated by Jacoco
*/
public val xml: Report = objects.newInstance(Report::class.java)
public val xml: FileReport = objects.newInstance(FileReport::class.java)

/**
* List of class name patterns that should be excluded from being processed by Jacoco.
Expand All @@ -54,24 +58,36 @@ public abstract class JacocoOptions @Inject constructor(
@get:Input
public abstract val excludedClasses: ListProperty<String>

public abstract class Report {

public operator fun invoke(config: Report.() -> Unit) {
this.config()
}

public sealed class Report {
/**
* Whether this report should be generated
*/
@get:Input
public abstract val enabled: Property<Boolean>

/**
* Name of the file to be generated; note that
* Name of the file/directory to be generated; note that
* due to the variant-aware nature of the plugin,
* each variant will be assigned a distinct folder if necessary
*/
public abstract val destination: FileSystemLocationProperty<out FileSystemLocation>
}

public abstract class DirectoryReport : Report() {
@get:Input
public abstract val destination: RegularFileProperty
public abstract override val destination: DirectoryProperty

public operator fun invoke(config: DirectoryReport.() -> Unit) {
this.config()
}
}

public abstract class FileReport : Report() {
@get:Input
public abstract override val destination: RegularFileProperty

public operator fun invoke(config: FileReport.() -> Unit) {
this.config()
}
}
}
Loading

0 comments on commit 220f5b8

Please sign in to comment.