diff --git a/build.gradle b/build.gradle index 331b779a..883b3ebc 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,7 @@ buildscript { exclude module: 'kotlin-compiler-embeddable' exclude module: 'kotlin-stdlib' } + classpath gradlePlugins.jacocoAndroid } } @@ -30,7 +31,9 @@ allprojects { } } +apply from: 'gradle_scripts/jacoco.gradle' + task wrapper(type: Wrapper) { - gradleVersion = versions.gradle - distributionType = "all" -} \ No newline at end of file + gradleVersion(versions.gradle) + distributionType("all") +} diff --git a/dependencies.gradle b/dependencies.gradle index 33aa431a..afe3d3a7 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -9,6 +9,8 @@ ext.versions = [ ktlint : "0.9.0", ktlintGradle : "2.1.0", detekt : "1.0.0.M13.2", + jacoco : "0.7.9", + jacocoAndroid : "0.1.2", androidSupport : "22.2.1", @@ -25,10 +27,11 @@ ext.versions = [ ] ext.gradlePlugins = [ - androidTools : "com.android.tools.build:gradle:$versions.androidTools", - kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin", - ktlintGradle : "gradle.plugin.org.jlleitschuh.gradle:ktlint-gradle:$versions.ktlintGradle", - detekt : "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$versions.detekt", + androidTools : "com.android.tools.build:gradle:$versions.androidTools", + kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin", + ktlintGradle : "gradle.plugin.org.jlleitschuh.gradle:ktlint-gradle:$versions.ktlintGradle", + detekt : "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$versions.detekt", + jacocoAndroid : "com.dicedmelon.gradle:jacoco-android:$versions.jacocoAndroid" ] ext.androidSupport = [ diff --git a/gradle_scripts/code_quality.gradle b/gradle_scripts/code_quality.gradle index 1954d03f..bc4fa9d4 100644 --- a/gradle_scripts/code_quality.gradle +++ b/gradle_scripts/code_quality.gradle @@ -25,4 +25,4 @@ if (isCodeQualityEnabled) { } } } -} \ No newline at end of file +} diff --git a/gradle_scripts/jacoco.gradle b/gradle_scripts/jacoco.gradle new file mode 100644 index 00000000..67a75609 --- /dev/null +++ b/gradle_scripts/jacoco.gradle @@ -0,0 +1,57 @@ +apply plugin: 'jacoco' + +task jacocoMergeReports(type: JacocoMerge) { + group = "Reporting" + description = "Merge all jacoco reports from projects into one." + + def subsonicApi = project.findProject("subsonic-api") + def ultrasonicApp = project.findProject("ultrasonic") + executionData( + "${subsonicApi.buildDir}/jacoco/test.exec", + "${ultrasonicApp.buildDir}/jacoco/testDebugUnitTest.exec", + ) + destinationFile(file("${project.buildDir}/jacoco/jacoco.exec")) +} + +def createJacocoFullReportTask() { + tasks.create(name: 'jacocoFullReport', type: JacocoReport, dependsOn: 'jacocoMergeReports') { + group = "Reporting" + description = "Generate full Jacoco coverage report including all modules." + + def subsonicApi = project.findProject("subsonic-api") + def ultrasonicApp = project.findProject("ultrasonic") + + classDirectories = files( + fileTree( + dir: "${subsonicApi.buildDir}/classes/main", + excludes: subsonicApi.jacocoExclude + ), + fileTree( + dir: "${ultrasonicApp.buildDir}/intermediates/classes/debug/org", + excludes: ultrasonicApp.jacocoExclude + ) + ) + sourceDirectories = files(subsonicApi.sourceSets.main.getAllSource(), + ultrasonicApp.extensions.getByName('android').sourceSets.main.java.sourceFiles) + executionData = files("${buildDir}/jacoco/jacoco.exec") + + reports { + xml.enabled = true + html.enabled = true + csv.enabled = false + } + } +} + +// We need to wait to all subprojects configuration finish or we don't get sources and exclusions +def subprojectsCount = allprojects.size() +allprojects { + afterEvaluate { subproject -> + subprojectsCount-- + if (subprojectsCount == 0) { + apply { + createJacocoFullReportTask() + } + } + } +} \ No newline at end of file diff --git a/subsonic-api/build.gradle b/subsonic-api/build.gradle index fa4fe445..4f4d0511 100644 --- a/subsonic-api/build.gradle +++ b/subsonic-api/build.gradle @@ -1,10 +1,11 @@ apply plugin: 'kotlin' +apply plugin: 'jacoco' apply from: '../gradle_scripts/code_quality.gradle' sourceSets { - main.java.srcDirs += 'src/main/kotlin' - test.java.srcDirs += 'src/integrationTest/kotlin' - test.resources.srcDirs += 'src/integrationTest/resources' + main.java.srcDirs += "${projectDir}/src/main/kotlin" + test.java.srcDirs += "${projectDir}/src/integrationTest/kotlin" + test.resources.srcDirs += "${projectDir}/src/integrationTest/resources" test.output.resourcesDir = test.output.classesDir } @@ -22,4 +23,36 @@ dependencies { testCompile testing.kluent testCompile testing.mockWebServer testCompile testing.apacheCodecs -} \ No newline at end of file +} + +jacoco { + toolVersion = versions.jacoco +} + +ext { + // Excluding data classes + jacocoExclude = [ + '**/models/**' + ] +} + +jacocoTestReport { + reports { + html.enabled true + csv.enabled false + xml.enabled true + } + + afterEvaluate { + classDirectories = files(classDirectories.files.collect { + fileTree(dir: it, excludes: jacocoExclude) + }) + } +} + +test.finalizedBy jacocoTestReport +test { + jacoco { + excludes += jacocoExclude + } +} diff --git a/ultrasonic/build.gradle b/ultrasonic/build.gradle index 790e163f..7875c1fd 100644 --- a/ultrasonic/build.gradle +++ b/ultrasonic/build.gradle @@ -1,5 +1,6 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +apply plugin: 'jacoco-android' apply from: "../gradle_scripts/code_quality.gradle" android { @@ -19,11 +20,15 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } + debug { + minifyEnabled false + testCoverageEnabled true + } } sourceSets { - main.java.srcDirs += 'src/main/kotlin' - test.java.srcDirs += 'src/test/kotlin' + main.java.srcDirs += "${projectDir}/src/main/kotlin" + test.java.srcDirs += "${projectDir}/src/test/kotlin" } packagingOptions { @@ -60,3 +65,29 @@ dependencies { exclude module: "kotlin-reflect" } } + +// Excluding all non-kotlin classes +ext { + jacocoExclude = [ + '**/activity/**', + '**/audiofx/**', + '**/domain/**', + '**/fragment/**', + '**/provider/**', + '**/receiver/**', + '**/service/**', + '**/Test/**', + '**/util/**', + '**/view/**', + '**/R$*.class', + '**/R.class', + '**/BuildConfig.class' + ] +} +jacocoAndroidUnitTestReport { + excludes += jacocoExclude +} + +afterEvaluate { + testDebugUnitTest.finalizedBy jacocoTestDebugUnitTestReport +}