├── settings.gradle ├── src ├── functionalTest │ ├── resources │ │ └── projects │ │ │ ├── scala-single-module │ │ │ ├── settings.gradle │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ ├── TestNothingSuite.scala │ │ │ │ │ └── WorldSuite.scala │ │ │ └── build.gradle │ │ │ ├── composite-build │ │ │ ├── proj1 │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── composite │ │ │ │ │ │ │ └── proj1 │ │ │ │ │ │ │ └── Foo.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── composite │ │ │ │ │ │ └── proj1 │ │ │ │ │ │ └── FooSuite.scala │ │ │ │ └── build.gradle │ │ │ └── proj2 │ │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── composite │ │ │ │ │ │ └── proj2 │ │ │ │ │ │ └── Reporter.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── composite │ │ │ │ │ └── proj2 │ │ │ │ │ └── ReporterSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── detect-scala-library │ │ │ ├── compile │ │ │ │ ├── settings.gradle │ │ │ │ └── build.gradle │ │ │ ├── compileOnly │ │ │ │ ├── settings.gradle │ │ │ │ └── build.gradle │ │ │ ├── implementation │ │ │ │ ├── settings.gradle │ │ │ │ └── build.gradle │ │ │ ├── dependency-management │ │ │ │ ├── settings.gradle │ │ │ │ └── build.gradle │ │ │ └── gradle-consistent-versions │ │ │ │ ├── settings.gradle │ │ │ │ ├── versions.props │ │ │ │ ├── versions.lock │ │ │ │ └── build.gradle │ │ │ ├── multiple-check-tasks │ │ │ ├── no-check │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── World.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── multiple-checks │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── World.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── old-and-new-syntax │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── World.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── single-check-new-syntax │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── World.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── build.gradle │ │ │ └── single-check-old-syntax │ │ │ │ ├── settings.gradle │ │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── scala-single-module-dependency-manager │ │ │ ├── settings.gradle │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldSuite.scala │ │ │ └── build.gradle │ │ │ ├── scala-single-module-multiple-test-tasks │ │ │ ├── settings.gradle │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ ├── intTest │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ ├── TestNothingSuite.scala │ │ │ │ │ │ └── WorldIntSuite.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldSuite.scala │ │ │ └── build.gradle │ │ │ ├── scala-multi-module-with-partial-scoverage-use │ │ │ ├── a │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── a │ │ │ │ │ └── WorldA.scala │ │ │ ├── b │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── b │ │ │ │ │ └── WorldB.scala │ │ │ ├── settings.gradle │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── World.scala │ │ │ └── build.gradle │ │ │ ├── scala-java-annotation-processor │ │ │ ├── lombok.config │ │ │ ├── settings.gradle │ │ │ ├── java_only │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── java │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldJavaOnly.java │ │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldJavaOnlyTest.java │ │ │ ├── mixed_scala_java │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ ├── java │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ │ └── WorldJava.java │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── WorldScala.scala │ │ │ │ │ └── test │ │ │ │ │ │ ├── java │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── WorldJavaTest.java │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldScalaSuite.scala │ │ │ │ └── build.gradle │ │ │ └── build.gradle │ │ │ ├── scala-multi-module │ │ │ ├── settings.gradle │ │ │ ├── a │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── a │ │ │ │ │ │ └── WorldA.scala │ │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── a │ │ │ │ │ ├── TestNothingASuite.scala │ │ │ │ │ └── WorldASuite.scala │ │ │ ├── b │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── b │ │ │ │ │ │ └── WorldB.scala │ │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── b │ │ │ │ │ ├── TestNothingBSuite.scala │ │ │ │ │ └── WorldBSuite.scala │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ ├── TestNothingSuite.scala │ │ │ │ │ └── WorldSuite.scala │ │ │ ├── common │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── common │ │ │ │ │ │ └── WorldCommon.scala │ │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── common │ │ │ │ │ ├── TestNothingCommonSuite.scala │ │ │ │ │ └── WorldCommonSuite.scala │ │ │ ├── dependencies │ │ │ │ └── build.gradle │ │ │ └── build.gradle │ │ │ ├── scala-multi-module-multiple-test-tasks │ │ │ ├── settings.gradle │ │ │ ├── a │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── test │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── a │ │ │ │ │ │ ├── TestNothingASuite.scala │ │ │ │ │ │ └── WorldASuite.scala │ │ │ │ │ ├── intTest │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── a │ │ │ │ │ │ └── WorldAIntSuite.scala │ │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── a │ │ │ │ │ └── WorldA.scala │ │ │ ├── b │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── test │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── b │ │ │ │ │ │ ├── TestNothingBSuite.scala │ │ │ │ │ │ └── WorldBSuite.scala │ │ │ │ │ ├── intTest │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── b │ │ │ │ │ │ └── WorldBIntSuite.scala │ │ │ │ │ └── main │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── b │ │ │ │ │ └── WorldB.scala │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World.scala │ │ │ │ ├── test │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ ├── TestNothingSuite.scala │ │ │ │ │ │ └── WorldSuite.scala │ │ │ │ └── intTest │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ ├── TestNothingSuite.scala │ │ │ │ │ └── WorldIntSuite.scala │ │ │ ├── common │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── common │ │ │ │ │ │ └── WorldCommon.scala │ │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── common │ │ │ │ │ ├── TestNothingCommonSuite.scala │ │ │ │ │ └── WorldCommonSuite.scala │ │ │ └── build.gradle │ │ │ ├── scala-java-multi-module │ │ │ ├── settings.gradle │ │ │ ├── java_only │ │ │ │ ├── build.gradle │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ └── java │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldJavaOnly.java │ │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldJavaOnlyTest.java │ │ │ ├── mixed_scala_java │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ ├── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ │ └── WorldScala.scala │ │ │ │ │ │ └── java │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── WorldJava.java │ │ │ │ │ └── test │ │ │ │ │ │ ├── java │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── WorldJavaTest.java │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldScalaSuite.scala │ │ │ │ └── build.gradle │ │ │ ├── scala_only │ │ │ │ ├── src │ │ │ │ │ ├── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ │ └── org │ │ │ │ │ │ │ └── hello │ │ │ │ │ │ │ └── WorldScalaOnly.scala │ │ │ │ │ └── test │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldScalaOnlySuite.scala │ │ │ │ └── build.gradle │ │ │ └── build.gradle │ │ │ └── multi-module-plugin-not-configured-for-scala │ │ │ ├── settings.gradle │ │ │ ├── java_only │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldJavaOnly.java │ │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── hello │ │ │ │ └── WorldJavaOnlyTest.java │ │ │ ├── scala_only │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── WorldScalaOnly.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── WorldScalaOnlySuite.scala │ │ │ └── build.gradle │ │ │ ├── dependencies │ │ │ └── build.gradle │ │ │ └── build.gradle │ └── java │ │ └── org │ │ └── scoverage │ │ ├── ScalaMultiModuleWithPartialScoverageUseTest.java │ │ ├── ScalaVersionArguments.java │ │ ├── ScalaSingleModuleWithDependencyManagerTest.java │ │ ├── CompositeBuildTest.java │ │ ├── MultiModulePluginNotConfiguredForScalaTest.java │ │ ├── ScalaJavaAnnotationProcessorTest.java │ │ ├── ScalaSingleModuleTestScala3.java │ │ ├── ScalaJavaMultiModuleTest.java │ │ ├── DetectScalaLibraryTest.java │ │ ├── MultipleCheckTasksTest.java │ │ ├── ScalaSingleModuleTest.java │ │ ├── ScoverageFunctionalTest.java │ │ ├── ScalaSingleModuleWithMultipleTestTasksTest.java │ │ ├── ScalaMultiModuleWithMultipleTestTasksTest.java │ │ └── ScalaMultiModuleTest.java ├── crossScalaVersionTest │ ├── resources │ │ └── projects │ │ │ └── scala-multi-module-cross-version │ │ │ ├── settings.gradle │ │ │ ├── 2_12 │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World2_12.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── World2_12Suite.scala │ │ │ └── build.gradle │ │ │ ├── 2_13 │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── scala │ │ │ │ │ │ └── org │ │ │ │ │ │ └── hello │ │ │ │ │ │ └── World2_13.scala │ │ │ │ └── test │ │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── World2_13Suite.scala │ │ │ └── build.gradle │ │ │ ├── 3_2 │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ ├── test │ │ │ │ └── scala │ │ │ │ │ └── org │ │ │ │ │ └── hello │ │ │ │ │ └── World3_2Suite.scala │ │ │ │ └── main │ │ │ │ └── scala │ │ │ │ └── org │ │ │ │ └── hello │ │ │ │ └── World3_2.scala │ │ │ └── build.gradle │ └── java │ │ └── org │ │ └── scoverage │ │ ├── Scala32Test.java │ │ ├── Scala212Test.java │ │ ├── Scala213Test.java │ │ ├── ScalaVersionTest.java │ │ └── ScalaCrossVersionAggregationTest.java ├── test │ ├── resources │ │ └── checkTask │ │ │ ├── cobertura.xml │ │ │ └── scoverage.xml │ └── groovy │ │ └── org │ │ └── scoverage │ │ └── CoverageCheckerTest.groovy └── main │ └── groovy │ └── org │ └── scoverage │ ├── ScoverageRunner.groovy │ ├── ScalaVersion.groovy │ ├── ScoverageReport.groovy │ ├── ScoverageAggregate.groovy │ ├── CoverageChecker.groovy │ ├── ScoverageExtension.groovy │ └── ScoverageWriter.java ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitattributes ├── .github └── workflows │ └── gradle.yml ├── gradlew.bat ├── README.md ├── gradlew └── LICENSE.txt /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='gradle-scoverage' -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj1/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/compile/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/no-check/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/compileOnly/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | classes 2 | build 3 | out 4 | .gradle 5 | 6 | *.iml 7 | *.ipr 8 | *.iws 9 | *.idea -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/implementation/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/multiple-checks/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/old-and-new-syntax/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-dependency-manager/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/dependency-management/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-new-syntax/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-old-syntax/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/a/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/b/build.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/settings.gradle: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.accessors.fluent=true 2 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'a', 'b' -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'dependencies', 'a', 'b', 'common' -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/settings.gradle: -------------------------------------------------------------------------------- 1 | include '2_12', '2_13', '3_2' -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'a', 'b', 'common' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scoverage/gradle-scoverage/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'java_only', 'mixed_scala_java' 2 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'java_only', 'scala_only', 'mixed_scala_java' -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/a/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":common") 3 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/b/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":common") 3 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.props: -------------------------------------------------------------------------------- 1 | org.scala-lang:scala-library = 2.12.0 -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'dependencies', 'java_only', 'scala_only' -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/a/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":common") 3 | } 4 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/b/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":common") 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.java text eol=lf 2 | *.MD text eol=lf 3 | *.gradle text eol=lf 4 | *.groovy text eol=lf 5 | *.properties text eol=lf 6 | *.scala text eol=lf 7 | -------------------------------------------------------------------------------- /src/crossScalaVersionTest/java/org/scoverage/Scala32Test.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | public class Scala32Test extends ScalaVersionTest { 4 | 5 | public Scala32Test() { super("3_2"); } 6 | } 7 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/java_only/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine' 3 | } 4 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/no-check/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | "a" + "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/java_only/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 3 | } 4 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/multiple-checks/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | "a" + "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | val s = "a" + "b" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/java/org/scoverage/Scala212Test.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | public class Scala212Test extends ScalaVersionTest { 4 | public Scala212Test() { 5 | super("2_12"); 6 | } 7 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/java/org/scoverage/Scala213Test.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | public class Scala213Test extends ScalaVersionTest { 4 | public Scala213Test() { 5 | super("2_13"); 6 | } 7 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/versions.lock: -------------------------------------------------------------------------------- 1 | # Run ./gradlew --write-locks to regenerate this file 2 | org.scala-lang:scala-library:2.12.0 (1 constraints: 3705353b) 3 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/old-and-new-syntax/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | "a" + "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/java_only/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 3 | } 4 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-new-syntax/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | "a" + "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-old-syntax/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | "a" + "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/a/src/main/scala/org/hello/a/WorldA.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | class WorldA { 4 | 5 | def fooA(): String = { 6 | "a" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/b/src/main/scala/org/hello/b/WorldB.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | class WorldB { 4 | 5 | def fooB(): String = { 6 | "b" 7 | } 8 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj1/src/main/scala/org/composite/proj1/Foo.scala: -------------------------------------------------------------------------------- 1 | package org.composite.proj1 2 | 3 | import org.composite.proj2.Reporter 4 | 5 | class Foo { 6 | def bar(): String = "bar" 7 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-dependency-manager/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | val s = "a" + "b" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_12/src/main/scala/org/hello/World2_12.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World2_12 { 4 | 5 | def foo(): String = { 6 | val s = "2" + "12" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_13/src/main/scala/org/hello/World2_13.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World2_13 { 4 | 5 | def foo(): String = { 6 | val s = "2" + "12" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/mixed_scala_java/src/main/scala/org/hello/WorldScala.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class WorldScala { 4 | 5 | def foo(): String = { 6 | val s = "scala" + "a" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/scala_only/src/main/scala/org/hello/WorldScalaOnly.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class WorldScalaOnly { 4 | 5 | def foo(): String = { 6 | val s = "scala_only" + "a" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/common/src/main/scala/org/hello/common/WorldCommon.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | class WorldCommon { 4 | 5 | def fooCommon(): String = { 6 | val s = "common" + "a" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/mixed_scala_java/src/main/java/org/hello/WorldJava.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import lombok.Value; 4 | 5 | @Value 6 | public class WorldJava { 7 | private final String foo = "java"; 8 | } 9 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/mixed_scala_java/src/main/scala/org/hello/WorldScala.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class WorldScala { 4 | private val worldJava = new WorldJava() 5 | 6 | def foo() = worldJava.foo() 7 | } 8 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/java_only/src/main/java/org/hello/WorldJavaOnly.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import lombok.Value; 4 | 5 | @Value 6 | public class WorldJavaOnly { 7 | private final String foo = "java_only"; 8 | } 9 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/scala_only/src/main/scala/org/hello/WorldScalaOnly.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class WorldScalaOnly { 4 | 5 | def foo(): String = { 6 | val s = "scala_only" + "a" 7 | s 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/mixed_scala_java/src/main/java/org/hello/WorldJava.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | public class WorldJava { 4 | 5 | public String foo() { 6 | String s = "java" + "a"; 7 | return s; 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/java_only/src/main/java/org/hello/WorldJavaOnly.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | public class WorldJavaOnly { 4 | 5 | public String foo() { 6 | String s = "java_only" + "a"; 7 | return s; 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | val s = "a" + "b" 7 | s 8 | } 9 | 10 | def bar(): String = "bar" 11 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | val s = "a" + "b" 7 | s 8 | } 9 | 10 | def bar(): String = "bar" 11 | } 12 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/common/src/main/scala/org/hello/common/WorldCommon.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | class WorldCommon { 4 | 5 | def fooCommon(): String = { 6 | val s = "common" + "a" 7 | s 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World { 4 | 5 | def foo(): String = { 6 | val s = "a" + "b" 7 | s 8 | } 9 | 10 | // not covered by tests 11 | def bar(): String = "y" 12 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/3_2/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation 'org.scala-lang:scala3-library_3:3.4.2' 3 | testImplementation 'org.scalatest:scalatest_3:3.2.16' 4 | testImplementation "org.scalatestplus:junit-4-13_3:3.2.16.0" 5 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/java_only/src/main/java/org/hello/WorldJavaOnly.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | public class WorldJavaOnly { 4 | 5 | public String foo() { 6 | String s = "java_only" + "a"; 7 | return s; 8 | } 9 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/a/src/main/scala/org/hello/a/WorldA.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.hello.common.WorldCommon 4 | 5 | class WorldA { 6 | 7 | def fooA(): String = { 8 | val s = "a" + new WorldCommon().fooCommon() 9 | s 10 | } 11 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/b/src/main/scala/org/hello/b/WorldB.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.hello.common.WorldCommon 4 | 5 | class WorldB { 6 | 7 | def fooB(): String = { 8 | val s = "b" + new WorldCommon().fooCommon() 9 | s 10 | } 11 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_12/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation group: 'org.scala-lang', name: 'scala-library', version: "2.12.17" 3 | testImplementation group: 'org.scalatest', name: "scalatest_2.12", version: scalatestVersion 4 | } 5 | -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_13/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation group: 'org.scala-lang', name: 'scala-library', version: "2.13.10" 3 | testImplementation group: 'org.scalatest', name: "scalatest_2.13", version: scalatestVersion 4 | } 5 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/mixed_scala_java/src/test/java/org/hello/WorldJavaTest.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import org.junit.Test; 4 | 5 | public class WorldJavaTest { 6 | 7 | @Test 8 | public void foo() { 9 | new WorldJava().foo(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/java_only/src/test/java/org/hello/WorldJavaOnlyTest.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import org.junit.Test; 4 | 5 | public class WorldJavaOnlyTest { 6 | 7 | @Test 8 | public void foo() { 9 | new WorldJavaOnly().foo(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/src/main/scala/org/hello/World.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.hello.a.WorldA 4 | import org.hello.a.WorldB 5 | 6 | class World { 7 | 8 | def foo(): String = { 9 | WorldA.foo() + WorldB.foo() 10 | } 11 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/mixed_scala_java/src/test/java/org/hello/WorldJavaTest.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import org.junit.Test; 4 | 5 | public class WorldJavaTest { 6 | 7 | @Test 8 | public void foo() { 9 | new WorldJava().foo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/java_only/src/test/java/org/hello/WorldJavaOnlyTest.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import org.junit.Test; 4 | 5 | public class WorldJavaOnlyTest { 6 | 7 | @Test 8 | public void foo() { 9 | new WorldJavaOnly().foo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/java_only/src/test/java/org/hello/WorldJavaOnlyTest.java: -------------------------------------------------------------------------------- 1 | package org.hello; 2 | 3 | import org.junit.Test; 4 | 5 | public class WorldJavaOnlyTest { 6 | 7 | @Test 8 | public void foo() { 9 | new WorldJavaOnly().foo(); 10 | } 11 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 4 | distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/src/test/scala/org/hello/TestNothingSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/a/src/test/scala/org/hello/a/TestNothingASuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingASuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/b/src/test/scala/org/hello/b/TestNothingBSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingBSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module/src/test/scala/org/hello/TestNothingSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.funsuite._ 5 | import org.scalatestplus.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingSuite extends AnyFunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/no-check/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/a/src/test/scala/org/hello/a/WorldASuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldASuite extends FunSuite { 9 | 10 | test("fooA") { 11 | new WorldA().fooA() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/b/src/test/scala/org/hello/b/WorldBSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldBSuite extends FunSuite { 9 | 10 | test("fooB") { 11 | new WorldB().fooB() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.funsuite._ 5 | import org.scalatestplus.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends AnyFunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/src/test/scala/org/hello/TestNothingSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/src/intTest/scala/org/hello/TestNothingSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj1/src/test/scala/org/composite/proj1/FooSuite.scala: -------------------------------------------------------------------------------- 1 | package org.composite.proj1 2 | 3 | import org.scalatest.FunSuite 4 | import org.junit.runner.RunWith 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class FooSuite extends FunSuite { 9 | 10 | test("bar"){ 11 | 12 | new Foo().bar() 13 | } 14 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/multiple-checks/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/old-and-new-syntax/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/src/intTest/scala/org/hello/TestNothingSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/common/src/test/scala/org/hello/common/TestNothingCommonSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingCommonSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-dependency-manager/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/compile/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'defines scala library using the "implementation" configuration' 10 | 11 | dependencies { 12 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${detectedScalaLibraryVersion}" 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/compileOnly/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'defines scala library using the "compileOnly" configuration' 10 | 11 | dependencies { 12 | compileOnly group: 'org.scala-lang', name: 'scala-library', version: "${detectedScalaLibraryVersion}" 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-new-syntax/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-old-syntax/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/a/src/test/scala/org/hello/a/TestNothingASuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingASuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/b/src/test/scala/org/hello/b/TestNothingBSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingBSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/src/test/scala/org/hello/WorldSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new World().foo() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/src/intTest/scala/org/hello/WorldIntSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldIntSuite extends FunSuite { 9 | 10 | test("bar") { 11 | new World().bar() 12 | } 13 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_13/src/test/scala/org/hello/World2_13Suite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class World212Suite extends FunSuite { 9 | 10 | test("foo") { 11 | new World2_13().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/implementation/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'defines scala library using the "implementation" configuration' 10 | 11 | dependencies { 12 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${detectedScalaLibraryVersion}" 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/mixed_scala_java/src/test/scala/org/hello/WorldScalaSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldScalaSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new WorldScala().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/a/src/test/scala/org/hello/a/WorldASuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldASuite extends FunSuite { 9 | 10 | test("fooA") { 11 | new WorldA().fooA() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/b/src/test/scala/org/hello/b/WorldBSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldBSuite extends FunSuite { 9 | 10 | test("fooB") { 11 | new WorldB().fooB() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/src/intTest/scala/org/hello/WorldIntSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldIntSuite extends FunSuite { 9 | 10 | test("bar") { 11 | new World().bar() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/2_12/src/test/scala/org/hello/World2_12Suite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class World2_12Suite extends FunSuite { 9 | 10 | test("foo") { 11 | new World2_12().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/scala_only/src/test/scala/org/hello/WorldScalaOnlySuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldScalaOnlySuite extends FunSuite { 9 | 10 | test("foo") { 11 | new WorldScalaOnly().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/a/src/intTest/scala/org/hello/a/WorldAIntSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldAIntSuite extends FunSuite { 9 | 10 | test("barA") { 11 | new WorldA().barA() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/b/src/intTest/scala/org/hello/b/WorldBIntSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldBIntSuite extends FunSuite { 9 | 10 | test("barB") { 11 | new WorldB().barB() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj2/src/main/scala/org/composite/proj2/Reporter.scala: -------------------------------------------------------------------------------- 1 | package org.composite.proj2 2 | 3 | class Reporter { 4 | 5 | def report(rawData: String): Report = { 6 | Report(1,2) 7 | } 8 | 9 | class InnerReporter { 10 | 11 | def lala(): Unit = { 12 | 13 | val x = 1 + 1 14 | x 15 | } 16 | } 17 | } 18 | 19 | case class Report(id: Long, count: Int) -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/mixed_scala_java/src/test/scala/org/hello/WorldScalaSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldScalaSuite extends FunSuite { 9 | 10 | test("foo") { 11 | new WorldScala().foo() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/a/src/main/scala/org/hello/a/WorldA.scala: -------------------------------------------------------------------------------- 1 | package org.hello.a 2 | 3 | import org.hello.common.WorldCommon 4 | 5 | class WorldA { 6 | 7 | def fooA(): String = { 8 | val s = "a" + new WorldCommon().fooCommon() 9 | s 10 | } 11 | 12 | def barA(): String = { 13 | val s = "a" + new WorldCommon().fooCommon() 14 | s 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/b/src/main/scala/org/hello/b/WorldB.scala: -------------------------------------------------------------------------------- 1 | package org.hello.b 2 | 3 | import org.hello.common.WorldCommon 4 | 5 | class WorldB { 6 | 7 | def fooB(): String = { 8 | val s = "b" + new WorldCommon().fooCommon() 9 | s 10 | } 11 | 12 | def barB(): String = { 13 | val s = "b" + new WorldCommon().fooCommon() 14 | s 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/common/src/test/scala/org/hello/common/TestNothingCommonSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class TestNothingCommonSuite extends FunSuite { 9 | 10 | test("nothing") { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/common/src/test/scala/org/hello/common/WorldCommonSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldCommonSuite extends FunSuite { 9 | 10 | test("fooCommon") { 11 | new WorldCommon().fooCommon() 12 | } 13 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/3_2/src/test/scala/org/hello/World3_2Suite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.funsuite.AnyFunSuite 5 | import org.scalatestplus.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class World3_2Suite extends AnyFunSuite { 9 | 10 | test("foo") { 11 | new World3_2().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/3_2/src/main/scala/org/hello/World3_2.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | class World3_2 { 4 | 5 | // Scala 3 enum to force Scala 3 (Dotty) compiler 6 | enum Num(val value: String): 7 | case Three extends Num("3") 8 | case Two extends Num("2") 9 | 10 | def foo(): String = { 11 | val s = Num.Three.value + Num.Two.value 12 | s 13 | } 14 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/scala_only/src/test/scala/org/hello/WorldScalaOnlySuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldScalaOnlySuite extends FunSuite { 9 | 10 | test("foo") { 11 | new WorldScalaOnly().foo() 12 | } 13 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/common/src/test/scala/org/hello/common/WorldCommonSuite.scala: -------------------------------------------------------------------------------- 1 | package org.hello.common 2 | 3 | import org.junit.runner.RunWith 4 | import org.scalatest.FunSuite 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class WorldCommonSuite extends FunSuite { 9 | 10 | test("fooCommon") { 11 | new WorldCommon().fooCommon() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj2/src/test/scala/org/composite/proj2/ReporterSuite.scala: -------------------------------------------------------------------------------- 1 | package org.composite.proj2 2 | 3 | import org.scalatest.FunSuite 4 | import org.junit.runner.RunWith 5 | import org.scalatest.junit.JUnitRunner 6 | 7 | @RunWith(classOf[JUnitRunner]) 8 | class ReporterSuite extends FunSuite { 9 | 10 | test("report"){ 11 | 12 | val report = new Reporter().report("x") 13 | 14 | assertResult(Report(1, 2))(report) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/scala_only/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'scala' 2 | // apply plugin: 'org.scoverage' // Oops forgot to configure scoverage 3 | 4 | dependencies { 5 | implementation group: 'org.scala-lang', name: 'scala-library' 6 | 7 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine' 8 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}" 9 | } 10 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/scala_only/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'scala' 2 | 3 | dependencies { 4 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 5 | 6 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 7 | 8 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 9 | } 10 | 11 | apply plugin: 'org.scoverage' 12 | scoverage { 13 | minimumRate = 0.5 14 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/mixed_scala_java/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'scala' 2 | 3 | dependencies { 4 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 5 | 6 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 7 | 8 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 9 | } 10 | 11 | apply plugin: 'org.scoverage' 12 | scoverage { 13 | minimumRate = 0.5 14 | } 15 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/dependency-management/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' version "1.1.5" 3 | id 'org.scoverage' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | description = 'defines scala library using the "implementation" configuration and the dependency-management plugin' 11 | 12 | dependencyManagement { 13 | dependencies { 14 | dependency group: 'org.scala-lang', name: 'scala-library', version: "${detectedScalaLibraryVersion}" 15 | } 16 | } 17 | 18 | dependencies { 19 | implementation group: 'org.scala-lang', name: 'scala-library' 20 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/dependencies/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-platform' 3 | } 4 | 5 | dependencies { 6 | constraints { 7 | api group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 8 | 9 | api group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 10 | api group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 11 | 12 | api group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 13 | } 14 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/detect-scala-library/gradle-consistent-versions/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.palantir.consistent-versions" version "1.28.0" 3 | id 'org.scoverage' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | description = 'defines scala library using the "implementation" configuration and the gradle-consistent-versions plugin' 11 | 12 | dependencies { 13 | implementation group: 'org.scala-lang', name: 'scala-library' 14 | } 15 | 16 | scoverage { 17 | // 'detectedScalaLibraryVersion' is set by the test `DetectScalaLibraryTest.java` 18 | scoverageScalaVersion = detectedScalaLibraryVersion 19 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/dependencies/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-platform' 3 | } 4 | 5 | dependencies { 6 | constraints { 7 | api group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 8 | 9 | api group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 10 | api group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 11 | 12 | api group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 13 | } 14 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | description = 'a multi-module Scala and Java project that builds successfully with 100% coverage' 6 | 7 | allprojects { 8 | repositories { 9 | mavenCentral() 10 | } 11 | } 12 | 13 | subprojects { 14 | apply plugin: 'java' 15 | 16 | dependencies { 17 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 18 | } 19 | 20 | test { 21 | useJUnitPlatform() 22 | } 23 | } 24 | 25 | apply plugin: 'org.scoverage' 26 | scoverage { 27 | minimumRate = 0.5 28 | } -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaMultiModuleWithPartialScoverageUseTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Test; 4 | 5 | public class ScalaMultiModuleWithPartialScoverageUseTest extends ScoverageFunctionalTest { 6 | 7 | public ScalaMultiModuleWithPartialScoverageUseTest() { 8 | super("scala-multi-module-with-partial-scoverage-use"); 9 | } 10 | 11 | @Test 12 | public void reportScoverage() { 13 | 14 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME()); 15 | 16 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 17 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multi-module-plugin-not-configured-for-scala/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | description = 'a multi-module Scala and Java project that defines scoverage only on root but not on subprojects' 6 | 7 | allprojects { 8 | repositories { 9 | mavenCentral() 10 | } 11 | } 12 | 13 | subprojects { p -> 14 | if (p.name != 'dependencies') { 15 | apply plugin: 'java' 16 | dependencies { 17 | implementation platform(project(':dependencies')) 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner' 19 | } 20 | 21 | test { 22 | useJUnitPlatform() 23 | } 24 | } 25 | } 26 | 27 | apply plugin: 'org.scoverage' 28 | scoverage { 29 | minimumRate = 0.5 30 | } -------------------------------------------------------------------------------- /src/test/resources/checkTask/cobertura.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/no-check/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project with no check configured' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 16 | 17 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 19 | 20 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-multi-module/mixed_scala_java/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'scala' 2 | 3 | dependencies { 4 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 5 | 6 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 7 | 8 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 9 | } 10 | 11 | // A common practice in mixed java/scala modules to make Java code able to import Scala code 12 | ext.configureSources = { set, name -> 13 | set.scala.srcDir("src/$name/java") 14 | set.java.srcDirs = [] 15 | } 16 | configureSources(sourceSets.main, 'main') 17 | configureSources(sourceSets.test, 'test') 18 | 19 | apply plugin: 'org.scoverage' 20 | scoverage { 21 | minimumRate = 0.5 22 | } -------------------------------------------------------------------------------- /src/crossScalaVersionTest/resources/projects/scala-multi-module-cross-version/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | allprojects { 6 | repositories { 7 | mavenCentral() 8 | } 9 | } 10 | 11 | description = 'a multi-module Scala project with multiple Scala versions that builds successfully with 100% coverage' 12 | 13 | allprojects { 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'scala' 17 | apply plugin: 'org.scoverage' 18 | 19 | dependencies { 20 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 21 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 22 | } 23 | 24 | test { 25 | useJUnitPlatform() 26 | } 27 | 28 | scoverage { 29 | minimumRate = 0.5 30 | } 31 | } 32 | 33 | scoverage { 34 | minimumRate = 0.5 35 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj2/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project taking part in a composite build (2)' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | 15 | group "org.composite" 16 | version '1.0' 17 | 18 | dependencies { 19 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 20 | 21 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 22 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 23 | 24 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 25 | } 26 | 27 | test { 28 | useJUnitPlatform() 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/composite-build/proj1/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project taking part in a composite build (1)' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | 15 | group "org.composite" 16 | version '1.0' 17 | 18 | dependencies { 19 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 20 | 21 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 22 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 23 | 24 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 25 | 26 | implementation "org.composite:proj2:1.0" 27 | } 28 | 29 | test { 30 | useJUnitPlatform() 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScoverageRunner.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import org.gradle.api.file.FileCollection 4 | import org.gradle.api.tasks.Classpath 5 | 6 | import java.lang.reflect.Method 7 | 8 | class ScoverageRunner { 9 | 10 | @Classpath 11 | final FileCollection runtimeClasspath 12 | 13 | ScoverageRunner(FileCollection runtimeClasspath) { 14 | 15 | this.runtimeClasspath = runtimeClasspath 16 | } 17 | 18 | def run(Closure action) { 19 | 20 | URLClassLoader cloader = (URLClassLoader) Thread.currentThread().getContextClassLoader() 21 | 22 | Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class) 23 | method.setAccessible(true) 24 | 25 | runtimeClasspath.files.each { f -> 26 | def url = f.toURI().toURL() 27 | if (!cloader.getURLs().contains(url)) { 28 | method.invoke(cloader, url) 29 | } 30 | } 31 | 32 | action.call() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-with-partial-scoverage-use/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | description = 'a multi-module Scala project that builds successfully and has modules which does not use scoverate plugin' 6 | 7 | allprojects { p -> 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | apply plugin: 'java' 13 | apply plugin: 'scala' 14 | 15 | if (p.name != 'a') { 16 | apply plugin: 'org.scoverage' 17 | } 18 | 19 | dependencies { 20 | 21 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 22 | 23 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner' 24 | 25 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}" 26 | } 27 | } 28 | 29 | dependencies { 30 | implementation project(':a') 31 | implementation project(':b') 32 | } -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-old-syntax/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project that has a single check configurations (with the old syntax)' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 16 | 17 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 19 | 20 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } 26 | 27 | scoverage { 28 | minimumRate = 0.3 29 | coverageType = org.scoverage.CoverageType.Line 30 | } 31 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/single-check-new-syntax/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project that has a single check configurations (with the new syntax)' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 16 | 17 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 19 | 20 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } 26 | 27 | scoverage { 28 | check { 29 | minimumRate = 0.3 30 | coverageType = org.scoverage.CoverageType.Line 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | description = 'a multi-module Scala project that builds successfully with 100% coverage' 6 | 7 | allprojects { p -> 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | if (p.name != 'dependencies') { 13 | apply plugin: 'java' 14 | apply plugin: 'scala' 15 | apply plugin: 'org.scoverage' 16 | 17 | dependencies { 18 | implementation platform(project(':dependencies')) 19 | 20 | implementation group: 'org.scala-lang', name: 'scala-library' 21 | 22 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine' 23 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner' 24 | 25 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}" 26 | } 27 | 28 | test { 29 | useJUnitPlatform() 30 | } 31 | 32 | scoverage { 33 | minimumRate = 0.5 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaVersionArguments.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | public interface ScalaVersionArguments { 7 | List version2WithLegacyScalatest = Arrays.asList( 8 | "-PscalaVersionMajor=2", 9 | "-PscalaVersionMinor=13", 10 | "-PscalaVersionBuild=14", 11 | "-PjunitVersion=5.3.2", 12 | "-PjunitPlatformVersion=1.3.2", 13 | "-PscalatestVersion=3.0.8" 14 | ); 15 | 16 | List version2 = Arrays.asList( 17 | "-PscalaVersionMajor=2", 18 | "-PscalaVersionMinor=13", 19 | "-PscalaVersionBuild=14", 20 | "-PjunitVersion=5.3.2", 21 | "-PjunitPlatformVersion=1.3.2", 22 | "-PscalatestVersion=3.2.16" 23 | ); 24 | 25 | List version3 = Arrays.asList( 26 | "-PscalaVersionMajor=3", 27 | "-PscalaVersionMinor=4", 28 | "-PscalaVersionBuild=2", 29 | "-PjunitVersion=5.3.2", 30 | "-PjunitPlatformVersion=1.3.2", 31 | "-PscalatestVersion=3.2.16" 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaSingleModuleWithDependencyManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class ScalaSingleModuleWithDependencyManagerTest extends ScoverageFunctionalTest { 7 | 8 | public ScalaSingleModuleWithDependencyManagerTest() { 9 | super("scala-single-module-dependency-manager"); 10 | } 11 | 12 | @Test 13 | public void checkScoverage() throws Exception { 14 | 15 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME()); 16 | 17 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 18 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 19 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 20 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 21 | 22 | assertReportFilesExist(); 23 | assertCoverage(100.0); 24 | } 25 | 26 | private void assertReportFilesExist() { 27 | 28 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 29 | Assert.assertTrue(resolve(reportDir(), "org/hello/World.scala.html").exists()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-dependency-manager/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' version "1.1.5" 3 | id 'org.scoverage' 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | description = 'a single-module Scala project with dependency manager that builds successfully with 100% coverage' 11 | 12 | apply plugin: 'java' 13 | apply plugin: 'scala' 14 | 15 | 16 | dependencyManagement { 17 | dependencies { 18 | dependency group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation group: 'org.scala-lang', name: 'scala-library' 24 | 25 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 26 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 27 | 28 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 29 | } 30 | 31 | test { 32 | useJUnitPlatform() 33 | } 34 | 35 | scoverage { 36 | minimumRate = 0.3 37 | } 38 | 39 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | include: 18 | - name: 'ignore warnings' 19 | additional-check-args: '' 20 | continue-on-error: false 21 | - name: 'fail on warning' 22 | additional-check-args: '--warning-mode=fail -PfailOnWarning' 23 | continue-on-error: true 24 | 25 | runs-on: ubuntu-latest 26 | continue-on-error: ${{ matrix.continue-on-error }} 27 | 28 | steps: 29 | - uses: actions/checkout@v2 30 | - name: Set up JDK 11 31 | uses: actions/setup-java@v2 32 | with: 33 | java-version: '11' 34 | distribution: 'adopt' 35 | - name: Grant execute permission for gradlew 36 | run: chmod +x gradlew 37 | - name: Build with Gradle 38 | run: ./gradlew --info --stacktrace check ${{ matrix.additional-check-args }} 39 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/old-and-new-syntax/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project that has multiple check configurations - some new syntax, some old' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 16 | 17 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 19 | 20 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } 26 | 27 | scoverage { 28 | minimumRate = 0.3 29 | coverageType = org.scoverage.CoverageType.Line 30 | check { 31 | minimumRate = 0.1 32 | coverageType = org.scoverage.CoverageType.Branch 33 | } 34 | check { 35 | minimumRate = 0.6 36 | coverageType = org.scoverage.CoverageType.Statement 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/multiple-check-tasks/multiple-checks/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project that has multiple check configurations' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 16 | 17 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 18 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 19 | 20 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } 26 | 27 | scoverage { 28 | check { 29 | minimumRate = 0.3 30 | coverageType = org.scoverage.CoverageType.Line 31 | } 32 | check { 33 | minimumRate = 0.1 34 | coverageType = org.scoverage.CoverageType.Branch 35 | } 36 | check { 37 | minimumRate = 0.6 38 | coverageType = org.scoverage.CoverageType.Statement 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/CompositeBuildTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | /** 11 | * Tests are currently ignored as composite builds are not supported yet. 12 | * 13 | * @see Issue #94. 14 | */ 15 | public class CompositeBuildTest extends ScoverageFunctionalTest { 16 | 17 | public CompositeBuildTest() { 18 | super("composite-build"); 19 | } 20 | 21 | @Test 22 | public void buildComposite() { 23 | 24 | runComposite("clean", "build"); 25 | } 26 | 27 | @Test 28 | public void reportComposite() { 29 | 30 | runComposite("clean", ScoveragePlugin.getREPORT_NAME()); 31 | } 32 | 33 | private AssertableBuildResult runComposite(String... arguments) { 34 | 35 | List fullArguments = new ArrayList<>(); 36 | fullArguments.add("-p"); 37 | fullArguments.add("proj1"); 38 | fullArguments.add("--include-build"); 39 | fullArguments.add("../proj2"); 40 | fullArguments.addAll(Arrays.asList(arguments)); 41 | 42 | return run(fullArguments.toArray(new String[0])); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/crossScalaVersionTest/java/org/scoverage/ScalaVersionTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * This abstract class is used to test each scala version in an individual class. 10 | * It is crucial that each test will be separated into its own class, 11 | * as this is the only way to run these tests in separate JVM processes (via `forkEvery` gradle configuration). 12 | */ 13 | public abstract class ScalaVersionTest extends ScoverageFunctionalTest { 14 | 15 | private final String scalaVersion; 16 | 17 | public ScalaVersionTest(String scalaVersion) { 18 | super("scala-multi-module-cross-version"); 19 | this.scalaVersion = scalaVersion; 20 | } 21 | 22 | @Test 23 | public void report() throws Exception { 24 | 25 | AssertableBuildResult result = run("clean", ":" + scalaVersion + ":" + ScoveragePlugin.getREPORT_NAME()); 26 | result.assertTaskSucceeded(scalaVersion + ":" + ScoveragePlugin.getREPORT_NAME()); 27 | 28 | File reportDir = reportDir(projectDir().toPath().resolve(scalaVersion).toFile()); 29 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 30 | Assert.assertTrue(resolve(reportDir, "org/hello/World" + scalaVersion + ".scala.html").exists()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScalaVersion.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | class ScalaVersion { 4 | final String primaryVersion 5 | final Optional secondaryVersion 6 | final Integer majorVersion 7 | final String scalacScoverageVersion 8 | final String scalacScoveragePluginVersion 9 | final String scalacScoverageRuntimeVersion 10 | 11 | ScalaVersion(primaryVersion) { 12 | this(primaryVersion, Optional.empty()) 13 | } 14 | 15 | ScalaVersion(String primaryVersion, Optional secondaryVersion) { 16 | this.primaryVersion = primaryVersion 17 | this.secondaryVersion = secondaryVersion 18 | 19 | this.majorVersion = primaryVersion.substring(0, primaryVersion.indexOf('.')).toInteger() 20 | this.scalacScoverageVersion = this.majorVersion < 3 21 | ? primaryVersion.substring(0, primaryVersion.lastIndexOf('.')) 22 | : this.majorVersion.toString() 23 | this.scalacScoveragePluginVersion = secondaryVersion.orElse(primaryVersion) 24 | this.scalacScoverageRuntimeVersion = scalacScoveragePluginVersion.substring(0, scalacScoveragePluginVersion.lastIndexOf('.')) 25 | } 26 | 27 | @Override 28 | String toString() { 29 | return majorVersion < 3 ? primaryVersion : "$primaryVersion (${secondaryVersion.get()})" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/crossScalaVersionTest/java/org/scoverage/ScalaCrossVersionAggregationTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class ScalaCrossVersionAggregationTest extends ScoverageFunctionalTest { 7 | 8 | public ScalaCrossVersionAggregationTest() { 9 | super("scala-multi-module-cross-version"); 10 | } 11 | 12 | @Test 13 | public void checkAndAggregateAll() throws Exception { 14 | 15 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 16 | ScoveragePlugin.getAGGREGATE_NAME()); 17 | 18 | result.assertTaskSkipped(ScoveragePlugin.getREPORT_NAME()); 19 | result.assertTaskSucceeded("2_12:" + ScoveragePlugin.getREPORT_NAME()); 20 | result.assertTaskSucceeded("2_13:" + ScoveragePlugin.getREPORT_NAME()); 21 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 22 | result.assertTaskSucceeded("2_12:" + ScoveragePlugin.getCHECK_NAME()); 23 | result.assertTaskSucceeded("2_13:" + ScoveragePlugin.getCHECK_NAME()); 24 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 25 | 26 | assertAggregationFilesExist(); 27 | assertCoverage(100.0); 28 | } 29 | 30 | private void assertAggregationFilesExist() { 31 | 32 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 33 | Assert.assertTrue(resolve(reportDir(), "org/hello/World2_12.scala.html").exists()); 34 | Assert.assertTrue(resolve(reportDir(), "org/hello/World2_13.scala.html").exists()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-java-annotation-processor/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | description = 'a multi-module Scala and Java project using a Java annotation processor' 6 | 7 | allprojects { 8 | repositories { 9 | mavenCentral() 10 | } 11 | } 12 | 13 | def lombokVersion = '1.18.20' 14 | 15 | subprojects { 16 | apply plugin: 'java' 17 | 18 | dependencies { 19 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 20 | 21 | compileOnly "org.projectlombok:lombok:$lombokVersion" 22 | annotationProcessor "org.projectlombok:lombok:$lombokVersion" 23 | 24 | testCompileOnly "org.projectlombok:lombok:$lombokVersion" 25 | testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion" 26 | } 27 | 28 | test { 29 | useJUnitPlatform() 30 | } 31 | } 32 | 33 | /* 34 | Because the Scala compiler doesn't support annotation processors, Java files using a Java annotation 35 | processor MUST be compiled by the Java compiler. So we can't use the same 36 | configuration as in `scala-java-multi-module` here. 37 | 38 | // A common practice in mixed java/scala modules to make Java code able to import Scala code 39 | ext.configureSources = { set, name -> 40 | set.scala.srcDir("src/$name/java") 41 | set.java.srcDirs = [] 42 | } 43 | configureSources(sourceSets.main, 'main') 44 | configureSources(sourceSets.test, 'test') 45 | */ 46 | 47 | apply plugin: 'org.scoverage' 48 | scoverage { 49 | minimumRate = 0.5 50 | } 51 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | } 8 | 9 | description = 'a single-module Scala project that builds successfully with 50% coverage' 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'scala' 13 | 14 | dependencies { 15 | if (project.getProperties().get("scalaVersionMajor").equals("2")) { 16 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 17 | 18 | testImplementation group: 'org.scalatest', name: 'scalatest_2.13', version: scalatestVersion 19 | testImplementation group: 'org.scalatestplus', name: 'junit-4-13_2.13', version: "${scalatestVersion}.0" 20 | } else { 21 | implementation group: 'org.scala-lang', name: 'scala3-library_3', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 22 | 23 | testImplementation group: 'org.scalatest', name: 'scalatest_3', version: scalatestVersion 24 | testImplementation group: 'org.scalatestplus', name: 'junit-4-13_3', version: "${scalatestVersion}.0" 25 | } 26 | 27 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 28 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 29 | } 30 | 31 | test { 32 | useJUnitPlatform() 33 | } 34 | 35 | scoverage { 36 | minimumRate = 0.3 37 | coverageType = org.scoverage.CoverageType.Line 38 | // verify that debug mode works 39 | coverageDebug = true 40 | } 41 | 42 | if (hasProperty("excludedFile")) { 43 | scoverage.excludedFiles = [excludedFile] 44 | } 45 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/MultiModulePluginNotConfiguredForScalaTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class MultiModulePluginNotConfiguredForScalaTest extends ScoverageFunctionalTest { 7 | 8 | public MultiModulePluginNotConfiguredForScalaTest() { 9 | super("multi-module-plugin-not-configured-for-scala"); 10 | } 11 | 12 | @Test 13 | public void checkAndAggregateScoverage() throws Exception { 14 | 15 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 16 | ScoveragePlugin.getAGGREGATE_NAME()); 17 | 18 | result.assertTaskSkipped(ScoveragePlugin.getREPORT_NAME()); 19 | result.assertTaskSkipped("scala_only:" + ScoveragePlugin.getREPORT_NAME()); 20 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getREPORT_NAME()); 21 | result.assertTaskSkipped(ScoveragePlugin.getCHECK_NAME()); 22 | result.assertTaskSkipped("scala_only:" + ScoveragePlugin.getCHECK_NAME()); 23 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getCHECK_NAME()); 24 | result.assertTaskSkipped(ScoveragePlugin.getAGGREGATE_NAME()); 25 | 26 | assertReportDirsEmpty(); 27 | 28 | Assert.assertTrue(result.getResult().getOutput().contains("Scala sub-project 'scala_only' doesn't have Scoverage applied")); 29 | Assert.assertFalse(result.getResult().getOutput().contains("Scala sub-project 'java_only' doesn't have Scoverage applied")); 30 | } 31 | 32 | private void assertReportDirsEmpty() { 33 | 34 | Assert.assertFalse(reportDir().exists()); 35 | Assert.assertFalse(reportDir(projectDir().toPath().resolve("scala_only").toFile()).exists()); 36 | Assert.assertFalse(reportDir(projectDir().toPath().resolve("java_only").toFile()).exists()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaJavaAnnotationProcessorTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.gradle.testkit.runner.TaskOutcome; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | 9 | public class ScalaJavaAnnotationProcessorTest extends ScoverageFunctionalTest { 10 | 11 | public ScalaJavaAnnotationProcessorTest() { 12 | super("scala-java-annotation-processor"); 13 | } 14 | 15 | @Test 16 | public void checkAndAggregateScoverage() throws Exception { 17 | 18 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 19 | ScoveragePlugin.getAGGREGATE_NAME()); 20 | 21 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getCOMPILE_NAME()); 22 | 23 | result.assertTaskSkipped(ScoveragePlugin.getREPORT_NAME()); 24 | result.assertTaskSucceeded("mixed_scala_java:" + ScoveragePlugin.getREPORT_NAME()); 25 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getREPORT_NAME()); 26 | 27 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 28 | result.assertTaskSucceeded("mixed_scala_java:" + ScoveragePlugin.getCHECK_NAME()); 29 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getCHECK_NAME()); 30 | 31 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 32 | 33 | assertAllReportFilesExist(); 34 | assertCoverage(100.0); 35 | } 36 | 37 | private void assertAllReportFilesExist() { 38 | 39 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 40 | 41 | assertMixedScalaJavaReportFilesExist(); 42 | assertAggregationFilesExist(); 43 | } 44 | 45 | private void assertAggregationFilesExist() { 46 | 47 | Assert.assertTrue(resolve(reportDir(), "org/hello/WorldScala.scala.html").exists()); 48 | } 49 | 50 | private void assertMixedScalaJavaReportFilesExist() { 51 | 52 | File reportDir = reportDir(projectDir().toPath().resolve("mixed_scala_java").toFile()); 53 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 54 | Assert.assertTrue(resolve(reportDir, "org/hello/WorldScala.scala.html").exists()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-multi-module-multiple-test-tasks/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.scoverage' apply false 3 | } 4 | 5 | allprojects { 6 | repositories { 7 | mavenCentral() 8 | } 9 | } 10 | 11 | description = 'a multi-module Scala project that builds successfully with 100% coverage' 12 | 13 | allprojects { 14 | 15 | apply plugin: 'java' 16 | apply plugin: 'scala' 17 | apply plugin: 'org.scoverage' 18 | 19 | dependencies { 20 | implementation group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 21 | 22 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 23 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 24 | 25 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 26 | } 27 | 28 | testing { 29 | suites { 30 | configureEach { 31 | useJUnit() 32 | targets.configureEach { 33 | testTask.configure { 34 | maxParallelForks = 1 35 | } 36 | } 37 | } 38 | intTest(JvmTestSuite) { 39 | testType = TestSuiteType.INTEGRATION_TEST 40 | // dependencies { ... } does not appear to work as advertised? 41 | sources { 42 | scala { 43 | compileClasspath += sourceSets.test.compileClasspath + sourceSets.main.output + sourceSets.test.output 44 | runtimeClasspath += sourceSets.test.runtimeClasspath 45 | } 46 | } 47 | targets.configureEach { 48 | testTask.configure{ 49 | outputs.upToDateWhen { false } 50 | mustRunAfter(test) 51 | } 52 | } 53 | } 54 | } 55 | } 56 | check.dependsOn(testing.suites.intTest) 57 | 58 | scoverage { 59 | minimumRate = 0.5 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/functionalTest/resources/projects/scala-single-module-multiple-test-tasks/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.dependency-management' version "1.1.5" 3 | id 'org.scoverage' 4 | id 'jvm-test-suite' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | description = 'a single-module Scala project with dependency manager that builds successfully with 100% coverage' 12 | 13 | apply plugin: 'scala' 14 | 15 | 16 | dependencyManagement { 17 | dependencies { 18 | dependency group: 'org.scala-lang', name: 'scala-library', version: "${scalaVersionMajor}.${scalaVersionMinor}.${scalaVersionBuild}" 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation group: 'org.scala-lang', name: 'scala-library' 24 | 25 | testRuntimeOnly group: 'org.junit.vintage', name: 'junit-vintage-engine', version: junitVersion 26 | testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion 27 | 28 | testImplementation group: 'org.scalatest', name: "scalatest_${scalaVersionMajor}.${scalaVersionMinor}", version: scalatestVersion 29 | } 30 | 31 | testing { 32 | suites { 33 | configureEach { 34 | useJUnit() 35 | targets.configureEach { 36 | testTask.configure { 37 | maxParallelForks = 1 38 | } 39 | } 40 | } 41 | intTest(JvmTestSuite) { 42 | testType = TestSuiteType.INTEGRATION_TEST 43 | // dependencies { ... } does not appear to work as advertised? 44 | sources { 45 | scala { 46 | compileClasspath += sourceSets.test.compileClasspath + sourceSets.main.output + sourceSets.test.output 47 | runtimeClasspath += sourceSets.test.runtimeClasspath 48 | } 49 | } 50 | targets.configureEach { 51 | testTask.configure{ 52 | outputs.upToDateWhen { false } 53 | mustRunAfter(test) 54 | } 55 | } 56 | } 57 | } 58 | } 59 | check.dependsOn(testing.suites.intTest) 60 | 61 | scoverage { 62 | minimumRate = 0.6 63 | } 64 | 65 | if (hasProperty("excludedFile")) { 66 | scoverage.excludedFiles = [excludedFile] 67 | } 68 | -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScoverageReport.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import org.gradle.api.DefaultTask 4 | import org.gradle.api.file.FileCollection 5 | import org.gradle.api.provider.Property 6 | import org.gradle.api.tasks.CacheableTask 7 | import org.gradle.api.tasks.Input 8 | import org.gradle.api.tasks.InputDirectory 9 | import org.gradle.api.tasks.InputFiles 10 | import org.gradle.api.tasks.Nested 11 | import org.gradle.api.tasks.OutputDirectory 12 | import org.gradle.api.tasks.PathSensitive 13 | import org.gradle.api.tasks.TaskAction 14 | import scoverage.reporter.CoverageAggregator 15 | 16 | import static org.gradle.api.tasks.PathSensitivity.RELATIVE 17 | 18 | @CacheableTask 19 | class ScoverageReport extends DefaultTask { 20 | 21 | @Nested 22 | ScoverageRunner runner 23 | 24 | @InputDirectory 25 | @PathSensitive(RELATIVE) 26 | final Property dataDir = project.objects.property(File) 27 | 28 | @InputFiles 29 | @PathSensitive(RELATIVE) 30 | final Property sources = project.objects.property(FileCollection) 31 | 32 | @OutputDirectory 33 | final Property reportDir = project.objects.property(File) 34 | 35 | @Input 36 | final Property sourceEncoding = project.objects.property(String) 37 | 38 | @Input 39 | final Property coverageOutputCobertura = project.objects.property(Boolean) 40 | @Input 41 | final Property coverageOutputXML = project.objects.property(Boolean) 42 | @Input 43 | final Property coverageOutputHTML = project.objects.property(Boolean) 44 | @Input 45 | final Property coverageDebug = project.objects.property(Boolean) 46 | 47 | @TaskAction 48 | def report() { 49 | runner.run { 50 | reportDir.get().delete() 51 | reportDir.get().mkdirs() 52 | 53 | def sourceRoot = getProject().getRootDir() 54 | def coverage = CoverageAggregator.aggregate([dataDir.get()] as File[], sourceRoot) 55 | 56 | if (coverage.isEmpty()) { 57 | project.logger.info("[scoverage] Could not find coverage file, skipping...") 58 | } else { 59 | new ScoverageWriter(project.logger).write( 60 | sources.get().getFiles(), 61 | reportDir.get(), 62 | coverage.get(), 63 | sourceEncoding.get(), 64 | coverageOutputCobertura.get(), 65 | coverageOutputXML.get(), 66 | coverageOutputHTML.get(), 67 | coverageDebug.get()) 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaSingleModuleTestScala3.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | 5 | import java.util.List; 6 | 7 | public class ScalaSingleModuleTestScala3 extends ScalaSingleModuleTest { 8 | 9 | @Override 10 | protected List getVersionAgruments() { 11 | return ScalaVersionArguments.version3; 12 | } 13 | 14 | @Override 15 | public void checkScoverage() throws Exception { 16 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME()); 17 | 18 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 19 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 20 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 21 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 22 | 23 | assertReportFilesExist(); 24 | assertCoverage(66.67); 25 | } 26 | 27 | @Override 28 | public void reportScoverageWithExcludedClasses() throws Exception { 29 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 30 | "-PexcludedFile=.*"); 31 | 32 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 33 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 34 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 35 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 36 | 37 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 38 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 39 | assertCoverage(100.0); // coverage is 100 since no classes are covered 40 | 41 | // compiled class should exist in the default classes directory, but not in scoverage 42 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 43 | } 44 | 45 | @Override 46 | public void reportScoverageWithoutNormalCompilationAndWithExcludedClasses() throws Exception { 47 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 48 | "-PexcludedFile=.*", "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 49 | 50 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 51 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 52 | assertCoverage(100.0); // coverage is 100 since no classes are covered 53 | 54 | // compiled class should exist in the default classes directory, but not in scoverage 55 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaJavaMultiModuleTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | 8 | public class ScalaJavaMultiModuleTest extends ScoverageFunctionalTest { 9 | 10 | public ScalaJavaMultiModuleTest() { 11 | super("scala-java-multi-module"); 12 | } 13 | 14 | @Test 15 | public void checkAndAggregateScoverage() throws Exception { 16 | 17 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 18 | ScoveragePlugin.getAGGREGATE_NAME()); 19 | 20 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getCOMPILE_NAME()); 21 | 22 | result.assertTaskSkipped(ScoveragePlugin.getREPORT_NAME()); 23 | result.assertTaskSucceeded("scala_only:" + ScoveragePlugin.getREPORT_NAME()); 24 | result.assertTaskSucceeded("mixed_scala_java:" + ScoveragePlugin.getREPORT_NAME()); 25 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getREPORT_NAME()); 26 | 27 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 28 | result.assertTaskSucceeded("scala_only:" + ScoveragePlugin.getCHECK_NAME()); 29 | result.assertTaskSucceeded("mixed_scala_java:" + ScoveragePlugin.getCHECK_NAME()); 30 | result.assertTaskSkipped("java_only:" + ScoveragePlugin.getCHECK_NAME()); 31 | 32 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 33 | 34 | assertAllReportFilesExist(); 35 | assertCoverage(100.0); 36 | } 37 | 38 | private void assertAllReportFilesExist() { 39 | 40 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 41 | 42 | assertScalaOnlyReportFilesExist(); 43 | assertMixedScalaJavaReportFilesExist(); 44 | assertAggregationFilesExist(); 45 | } 46 | 47 | private void assertAggregationFilesExist() { 48 | 49 | Assert.assertTrue(resolve(reportDir(), "org/hello/WorldScalaOnly.scala.html").exists()); 50 | Assert.assertTrue(resolve(reportDir(), "org/hello/WorldScala.scala.html").exists()); 51 | } 52 | 53 | private void assertScalaOnlyReportFilesExist() { 54 | 55 | File reportDir = reportDir(projectDir().toPath().resolve("scala_only").toFile()); 56 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 57 | Assert.assertTrue(resolve(reportDir, "org/hello/WorldScalaOnly.scala.html").exists()); 58 | } 59 | 60 | private void assertMixedScalaJavaReportFilesExist() { 61 | 62 | File reportDir = reportDir(projectDir().toPath().resolve("mixed_scala_java").toFile()); 63 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 64 | Assert.assertTrue(resolve(reportDir, "org/hello/WorldScala.scala.html").exists()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScoverageAggregate.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import org.gradle.api.DefaultTask 4 | import org.gradle.api.file.FileCollection 5 | import org.gradle.api.provider.ListProperty 6 | import org.gradle.api.provider.Property 7 | import org.gradle.api.tasks.Input 8 | import org.gradle.api.tasks.InputFiles 9 | import org.gradle.api.tasks.Nested 10 | import org.gradle.api.tasks.OutputDirectory 11 | import org.gradle.api.tasks.PathSensitive 12 | import org.gradle.api.tasks.TaskAction 13 | import scoverage.reporter.CoverageAggregator 14 | 15 | import static org.gradle.api.tasks.PathSensitivity.RELATIVE 16 | 17 | class ScoverageAggregate extends DefaultTask { 18 | 19 | @Nested 20 | ScoverageRunner runner 21 | 22 | @InputFiles 23 | @PathSensitive(RELATIVE) 24 | final Property sources = project.objects.property(FileCollection) 25 | 26 | @OutputDirectory 27 | final Property reportDir = project.objects.property(File) 28 | 29 | @Input 30 | final ListProperty dirsToAggregateFrom = project.objects.listProperty(File) 31 | 32 | @Input 33 | final Property deleteReportsOnAggregation = project.objects.property(Boolean) 34 | 35 | @Input 36 | final Property sourceEncoding = project.objects.property(String) 37 | 38 | // TODO - consider separate options for `report` and `aggregate` tasks 39 | @Input 40 | final Property coverageOutputCobertura = project.objects.property(Boolean) 41 | @Input 42 | final Property coverageOutputXML = project.objects.property(Boolean) 43 | @Input 44 | final Property coverageOutputHTML = project.objects.property(Boolean) 45 | @Input 46 | final Property coverageDebug = project.objects.property(Boolean) 47 | 48 | ScoverageAggregate() { 49 | dirsToAggregateFrom.set([project.extensions.scoverage.dataDir.get()]) 50 | } 51 | 52 | @TaskAction 53 | def aggregate() { 54 | runner.run { 55 | reportDir.get().deleteDir() 56 | reportDir.get().mkdirs() 57 | 58 | def dirs = [] 59 | dirs.addAll(dirsToAggregateFrom.get()) 60 | def sourceRoot = getProject().getRootDir() 61 | def coverage = CoverageAggregator.aggregate(dirs.unique() as File[], sourceRoot) 62 | 63 | if (coverage.nonEmpty()) { 64 | new ScoverageWriter(project.logger).write( 65 | sources.get().getFiles(), 66 | reportDir.get(), 67 | coverage.get(), 68 | sourceEncoding.get(), 69 | coverageOutputCobertura.get(), 70 | coverageOutputXML.get(), 71 | coverageOutputHTML.get(), 72 | coverageDebug.get() 73 | ) 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/DetectScalaLibraryTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.Parameterized; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | import java.util.stream.Stream; 10 | 11 | import static org.hamcrest.MatcherAssert.assertThat; 12 | import static org.hamcrest.Matchers.containsString; 13 | import static org.hamcrest.Matchers.stringContainsInOrder; 14 | 15 | @RunWith(Parameterized.class) 16 | public class DetectScalaLibraryTest extends ScoverageFunctionalTest { 17 | 18 | private static final String SCALA_VERSION = "2.13"; 19 | private static final String SCALA_LIBRARY_PARAMETER = "-PdetectedScalaLibraryVersion="; 20 | 21 | @Parameterized.Parameter(0) 22 | public String projectDir; 23 | 24 | @Parameterized.Parameter(1) 25 | public String[] subVersions; 26 | 27 | @Parameterized.Parameter(2) 28 | public boolean detect; 29 | 30 | @Parameterized.Parameter(3) 31 | public String[] additionalParameters; 32 | 33 | @Parameterized.Parameters(name = "{index}: Project {0} ") 34 | public static Collection data() { 35 | Object[][] data = new Object[][]{ 36 | {"/compile", new String[] {".0", ".+"}, true, new String[0]}, 37 | {"/compileOnly", new String[] {".0", ".+"}, true, new String[0]}, 38 | {"/implementation", new String[] {".0", ".+"}, true, new String[0]}, 39 | {"/dependency-management", new String[] {".0", ".+"}, true, new String[0]}, 40 | // disabled until the consistent-versions plugin supports Gradle 7 41 | // {"/gradle-consistent-versions", new String[] {"ignored"}, false, new String[] {"--write-locks"}}, 42 | }; 43 | return Arrays.asList(data); 44 | } 45 | 46 | public DetectScalaLibraryTest() { 47 | super(null); 48 | } 49 | 50 | @Test 51 | public void test() { 52 | setProjectName("detect-scala-library" + projectDir); 53 | for (String subVersion : subVersions) { 54 | testWithParameter(SCALA_LIBRARY_PARAMETER + SCALA_VERSION + subVersion, detect); 55 | } 56 | } 57 | 58 | private void testWithParameter(String parameter, boolean detect) { 59 | 60 | String[] basicParameters = {"clean", parameter, "--info"}; 61 | String[] parameters = Stream.concat(Arrays.stream(basicParameters), Arrays.stream(additionalParameters)) 62 | .toArray(String[]::new); 63 | AssertableBuildResult result = dryRun(parameters); 64 | 65 | String output = result.getResult().getOutput(); 66 | if (detect) { 67 | assertThat(output, containsString("Detected scala library in compilation classpath")); 68 | } else { 69 | assertThat(output, containsString("Using configured Scala version")); 70 | } 71 | assertThat(output, stringContainsInOrder("Using scoverage scalac plugin", "for scala", SCALA_VERSION)); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/MultipleCheckTasksTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public abstract class MultipleCheckTasksTest extends ScoverageFunctionalTest { 7 | 8 | /* --- Abstract Test ---- */ 9 | 10 | private final boolean shouldSucceed; 11 | 12 | public MultipleCheckTasksTest(String projectDir, boolean shouldSucceed) { 13 | super("multiple-check-tasks/" + projectDir); 14 | this.shouldSucceed = shouldSucceed; 15 | } 16 | 17 | @Test 18 | public void test() { 19 | assertResult(run()); 20 | } 21 | 22 | protected abstract void assertResult(AssertableBuildResult result); 23 | 24 | protected void assertOutput(AssertableBuildResult result, CoverageType type, double minimumRate) { 25 | String expectedMessage = String.format("Checking coverage. Type: %s. Minimum rate: %s", type, minimumRate); 26 | Assert.assertTrue(result.getResult().getOutput().contains(expectedMessage)); 27 | } 28 | 29 | private AssertableBuildResult run() { 30 | if (shouldSucceed) { 31 | return run("clean", ScoveragePlugin.getCHECK_NAME(), "--info"); 32 | } else { 33 | return runAndFail(ScoveragePlugin.getCHECK_NAME(), "--info"); 34 | } 35 | } 36 | 37 | /* --- Test Classes ---- */ 38 | 39 | public static class MultipleChecks extends MultipleCheckTasksTest { 40 | public MultipleChecks() { 41 | super("multiple-checks", true); 42 | } 43 | @Override 44 | protected void assertResult(AssertableBuildResult result) { 45 | 46 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 47 | assertOutput(result, CoverageType.Line, 0.3); 48 | assertOutput(result, CoverageType.Branch, 0.1); 49 | assertOutput(result, CoverageType.Statement, 0.6); 50 | 51 | } 52 | } 53 | public static class SingleCheckNewSyntax extends MultipleCheckTasksTest { 54 | public SingleCheckNewSyntax() { 55 | super("single-check-new-syntax", true); 56 | } 57 | @Override 58 | protected void assertResult(AssertableBuildResult result) { 59 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 60 | assertOutput(result, CoverageType.Line, 0.3); 61 | } 62 | } 63 | public static class SingleCheckOldSyntax extends MultipleCheckTasksTest { 64 | public SingleCheckOldSyntax() { 65 | super("single-check-old-syntax", true); 66 | } 67 | @Override 68 | protected void assertResult(AssertableBuildResult result) { 69 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 70 | assertOutput(result, CoverageType.Line, 0.3); 71 | } 72 | } 73 | public static class OldAndNewSyntax extends MultipleCheckTasksTest { 74 | public OldAndNewSyntax() { 75 | super("old-and-new-syntax", false); 76 | } 77 | @Override 78 | protected void assertResult(AssertableBuildResult result) { 79 | } 80 | } 81 | public static class NoCheck extends MultipleCheckTasksTest { 82 | public NoCheck() { 83 | super("no-check", true); 84 | } 85 | @Override 86 | protected void assertResult(AssertableBuildResult result) { 87 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 88 | assertOutput(result, ScoverageExtension.DEFAULT_COVERAGE_TYPE, ScoverageExtension.DEFAULT_MINIMUM_RATE); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/CoverageChecker.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import groovy.xml.XmlParser 4 | import org.gradle.api.GradleException 5 | import org.gradle.api.logging.Logger 6 | import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesting 7 | 8 | import java.text.DecimalFormat 9 | import java.text.DecimalFormatSymbols 10 | 11 | /** 12 | * Handles different types of coverage Scoverage can measure. 13 | */ 14 | enum CoverageType { 15 | Line('Line', 'cobertura.xml', 'line-rate', 1.0), 16 | Statement('Statement', 'scoverage.xml', 'statement-rate', 100.0), 17 | Branch('Branch', 'scoverage.xml', 'branch-rate', 100.0) 18 | 19 | /** Name of enum option the way it appears in the build configuration */ 20 | String configurationName 21 | /** Name of file with coverage data */ 22 | String fileName 23 | /** Name of param in XML file with coverage value */ 24 | String paramName 25 | /** Used to normalize coverage value */ 26 | private double factor 27 | 28 | private CoverageType(String configurationName, String fileName, String paramName, double factor) { 29 | this.configurationName = configurationName 30 | this.fileName = fileName 31 | this.paramName = paramName 32 | this.factor = factor 33 | } 34 | 35 | /** Normalize coverage value to [0, 1] */ 36 | Double normalize(Double value) { 37 | return value / factor 38 | } 39 | 40 | static CoverageType find(String configurationName) { 41 | CoverageType.values().find { 42 | it.configurationName.toLowerCase() == configurationName.toLowerCase() 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * Throws a GradleException if overall coverage dips below the configured percentage. 49 | */ 50 | class CoverageChecker { 51 | 52 | final Logger logger 53 | 54 | CoverageChecker(Logger logger) { 55 | this.logger = logger 56 | } 57 | 58 | public void checkLineCoverage(File reportDir, CoverageType coverageType, double minimumRate) throws GradleException { 59 | logger.info("Checking coverage. Type: {}. Minimum rate: {}", coverageType, minimumRate) 60 | 61 | XmlParser parser = new XmlParser() 62 | parser.setFeature('http://apache.org/xml/features/disallow-doctype-decl', false) 63 | parser.setFeature('http://apache.org/xml/features/nonvalidating/load-external-dtd', false) 64 | 65 | try { 66 | File reportFile = new File(reportDir, coverageType.fileName) 67 | Node xml = parser.parse(reportFile) 68 | Double coverageValue = (xml.attribute(coverageType.paramName) as String).toDouble() 69 | Double overallRate = coverageType.normalize(coverageValue) 70 | def difference = (minimumRate - overallRate) 71 | 72 | if (difference > 1e-7) { 73 | throw new GradleException(errorMsg(overallRate, minimumRate, coverageType)) 74 | } 75 | } catch (FileNotFoundException fnfe) { 76 | throw new GradleException(fileNotFoundErrorMsg(coverageType), fnfe) 77 | } 78 | } 79 | 80 | @VisibleForTesting 81 | protected static String errorMsg(double overallRate, double minimumRate, CoverageType type) { 82 | DecimalFormat df = new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(Locale.US)) 83 | String actual = df.format(overallRate * 100) 84 | String expected = df.format(minimumRate * 100) 85 | "Only $actual% of project is covered by tests instead of $expected% (coverageType: $type)" 86 | } 87 | 88 | @VisibleForTesting 89 | protected static String fileNotFoundErrorMsg(CoverageType coverageType) { 90 | "Coverage file (type: $coverageType) not found, check your configuration." 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/resources/checkTask/scoverage.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 8 | 9 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 31 | 32 | 34 | 35 | 37 | 38 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScoverageExtension.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import org.gradle.api.Project 4 | import org.gradle.api.plugins.JavaPlugin 5 | import org.gradle.api.plugins.scala.ScalaPlugin 6 | import org.gradle.api.provider.ListProperty 7 | import org.gradle.api.provider.Property 8 | 9 | /** 10 | * Defines a new SourceSet for the code to be instrumented. 11 | * Defines a new Test Task which executes normal tests with the instrumented classes. 12 | * Defines a new Check Task which enforces an overall line coverage requirement. 13 | */ 14 | class ScoverageExtension { 15 | 16 | public static final CoverageType DEFAULT_COVERAGE_TYPE = CoverageType.Statement 17 | public static final double DEFAULT_MINIMUM_RATE = 0.75 18 | 19 | final Project project 20 | 21 | /** Version of scoverage to use for the scalac plugin */ 22 | final Property scoverageVersion 23 | 24 | /** Version of scala to use for the scalac plugin */ 25 | final Property scoverageScalaVersion 26 | 27 | /** a directory to write working files to */ 28 | final Property dataDir 29 | /** a directory to write final output to */ 30 | final Property reportDir 31 | /** range positioning for highlighting */ 32 | final Property highlighting 33 | /** regex for each excluded package */ 34 | final ListProperty excludedPackages 35 | /** regex for each excluded file */ 36 | final ListProperty excludedFiles 37 | 38 | /** Options for enabling and disabling output */ 39 | final Property coverageOutputCobertura 40 | final Property coverageOutputXML 41 | final Property coverageOutputHTML 42 | final Property coverageDebug 43 | 44 | final Property deleteReportsOnAggregation 45 | 46 | final List checks = new ArrayList<>() 47 | 48 | final Property coverageType 49 | final Property minimumRate 50 | 51 | ScoverageExtension(Project project) { 52 | 53 | this.project = project 54 | project.plugins.apply(JavaPlugin.class) 55 | project.plugins.apply(ScalaPlugin.class) 56 | 57 | scoverageVersion = project.objects.property(String) 58 | scoverageVersion.set('2.1.1') 59 | 60 | scoverageScalaVersion = project.objects.property(String) 61 | 62 | dataDir = project.objects.property(File) 63 | dataDir.set(new File(project.buildDir, 'scoverage')) 64 | 65 | reportDir = project.objects.property(File) 66 | reportDir.set(new File(project.buildDir, ScoveragePlugin.DEFAULT_REPORT_DIR)) 67 | 68 | highlighting = project.objects.property(Boolean) 69 | highlighting.set(true) 70 | 71 | excludedPackages = project.objects.listProperty(String) 72 | excludedPackages.set([]) 73 | 74 | excludedFiles = project.objects.listProperty(String) 75 | excludedFiles.set([]) 76 | 77 | coverageOutputCobertura = project.objects.property(Boolean) 78 | coverageOutputCobertura.set(true) 79 | 80 | coverageOutputXML = project.objects.property(Boolean) 81 | coverageOutputXML.set(true) 82 | 83 | coverageOutputHTML = project.objects.property(Boolean) 84 | coverageOutputHTML.set(true) 85 | 86 | coverageDebug = project.objects.property(Boolean) 87 | coverageDebug.set(false) 88 | 89 | deleteReportsOnAggregation = project.objects.property(Boolean) 90 | deleteReportsOnAggregation.set(false) 91 | 92 | coverageType = project.objects.property(CoverageType) 93 | minimumRate = project.objects.property(BigDecimal) 94 | } 95 | 96 | void check(Closure closure) { 97 | CheckConfig check = new CheckConfig() 98 | project.configure(check, closure) 99 | checks.add(check) 100 | } 101 | 102 | static class CheckConfig { 103 | CoverageType coverageType 104 | BigDecimal minimumRate 105 | CheckConfig() { 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/test/groovy/org/scoverage/CoverageCheckerTest.groovy: -------------------------------------------------------------------------------- 1 | package org.scoverage 2 | 3 | import org.gradle.api.GradleException 4 | import org.hamcrest.Description 5 | import org.hamcrest.TypeSafeMatcher 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.jupiter.api.function.Executable 9 | import org.junit.rules.TemporaryFolder 10 | import org.slf4j.LoggerFactory 11 | 12 | import java.nio.file.Paths 13 | 14 | import static org.junit.Assert.assertEquals 15 | import static org.junit.Assert.assertThat 16 | import static org.junit.jupiter.api.Assertions.assertThrows 17 | 18 | class CoverageCheckerTest { 19 | 20 | private File reportDir = Paths.get(getClass().getClassLoader().getResource("checkTask").toURI()).toFile() 21 | 22 | private CoverageChecker checker = new CoverageChecker(LoggerFactory.getLogger(CoverageCheckerTest.class)) 23 | 24 | @Rule 25 | public TemporaryFolder tempDir = new TemporaryFolder() 26 | 27 | // error when report file is not there 28 | 29 | @Test 30 | void failsWhenReportFileIsNotFound() { 31 | assertFailure(CoverageChecker.fileNotFoundErrorMsg(CoverageType.Line), { 32 | checker.checkLineCoverage(tempDir.getRoot(), CoverageType.Line, 0.0) 33 | }) 34 | } 35 | 36 | // line coverage 37 | 38 | @Test 39 | void failsWhenLineRateIsBelowTarget() { 40 | assertFailure(CoverageChecker.errorMsg(0.66, 1.0, CoverageType.Line), { 41 | checker.checkLineCoverage(reportDir, CoverageType.Line, 1.0) 42 | }) 43 | } 44 | 45 | @Test 46 | void doesNotFailWhenLineRateIsAtTarget() { 47 | checker.checkLineCoverage(reportDir, CoverageType.Line, 0.66) 48 | } 49 | 50 | @Test 51 | void doesNotFailWhenLineRateIsAboveTarget() { 52 | checker.checkLineCoverage(reportDir, CoverageType.Line, 0.6) 53 | } 54 | 55 | // Statement coverage 56 | 57 | @Test 58 | void failsWhenStatementRateIsBelowTarget() { 59 | assertFailure(CoverageChecker.errorMsg(0.3333, 1.0, CoverageType.Statement), { 60 | checker.checkLineCoverage(reportDir, CoverageType.Statement, 1.0) 61 | }) 62 | } 63 | 64 | @Test 65 | void doesNotFailWhenStatementRateIsAtTarget() { 66 | checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.33) 67 | } 68 | 69 | @Test 70 | void doesNotFailWhenStatementRateIsAboveTarget() { 71 | checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.3) 72 | } 73 | 74 | // Branch coverage 75 | 76 | @Test 77 | void failsWhenBranchRateIsBelowTarget() { 78 | assertFailure(CoverageChecker.errorMsg(0.5, 1.0, CoverageType.Branch), { 79 | checker.checkLineCoverage(reportDir, CoverageType.Branch, 1.0) 80 | }) 81 | } 82 | 83 | @Test 84 | void doesNotFailWhenBranchRateIsAtTarget() { 85 | checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.5) 86 | } 87 | 88 | @Test 89 | void doesNotFailWhenBranchRateIsAboveTarget() { 90 | checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.45) 91 | } 92 | 93 | @Test 94 | void printsErrorMsgInEnglishWithUpTwoDecimalPointsPrecision() { 95 | assertEquals("Only 54.32% of project is covered by tests instead of 90% (coverageType: Branch)", 96 | CoverageChecker.errorMsg(0.54321, 0.9, CoverageType.Branch)) 97 | } 98 | 99 | private static void assertFailure(String message, Executable executable) { 100 | GradleException e = assertThrows(GradleException.class, executable) 101 | assertThat(e, new CauseMatcher(message)) 102 | } 103 | } 104 | 105 | /** 106 | * Copied from the Internet, just to check if we have correct exception thrown. 107 | */ 108 | class CauseMatcher extends TypeSafeMatcher { 109 | 110 | private final String expectedMessage 111 | 112 | CauseMatcher(String expectedMessage) { 113 | this.expectedMessage = expectedMessage 114 | } 115 | 116 | @Override 117 | protected boolean matchesSafely(GradleException item) { 118 | return item.getMessage().contains(expectedMessage) 119 | } 120 | 121 | @Override 122 | void describeTo(Description description) { 123 | description.appendText("expects message ") 124 | .appendValue(expectedMessage) 125 | } 126 | } -------------------------------------------------------------------------------- /src/main/groovy/org/scoverage/ScoverageWriter.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.gradle.api.logging.Logger; 4 | import scala.Option; 5 | import scala.Some; 6 | import scala.collection.immutable.Seq; 7 | import scala.collection.mutable.Buffer; 8 | import scoverage.domain.Constants; 9 | import scoverage.domain.Coverage; 10 | import scoverage.reporter.CoberturaXmlWriter; 11 | import scoverage.reporter.ScoverageHtmlWriter; 12 | import scoverage.reporter.ScoverageXmlWriter; 13 | import scala.collection.JavaConverters; 14 | 15 | import java.io.File; 16 | import java.lang.reflect.Constructor; 17 | import java.lang.reflect.InvocationTargetException; 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.Set; 21 | 22 | /** 23 | * Util for generating and saving coverage files. 24 | * Copied from sbt-scoverage and converted to Java to avoid dependency to Scala. 25 | */ 26 | public class ScoverageWriter { 27 | 28 | private final Logger logger; 29 | 30 | public ScoverageWriter(Logger logger) { 31 | 32 | this.logger = logger; 33 | } 34 | 35 | /** 36 | * Generates all reports from given data. 37 | * 38 | * @param sourceDirs directories with project sources 39 | * @param reportDir directory for generate reports 40 | * @param coverage coverage data 41 | * @param sourceEncoding the encoding of the source files 42 | * @param coverageOutputCobertura switch for Cobertura output 43 | * @param coverageOutputXML switch for Scoverage XML output 44 | * @param coverageOutputHTML switch for Scoverage HTML output 45 | * @param coverageDebug switch for Scoverage Debug output 46 | */ 47 | public void write(Set sourceDirs, 48 | File reportDir, 49 | Coverage coverage, 50 | String sourceEncoding, 51 | Boolean coverageOutputCobertura, 52 | Boolean coverageOutputXML, 53 | Boolean coverageOutputHTML, 54 | Boolean coverageDebug) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { 55 | 56 | logger.info("[scoverage] Generating scoverage reports..."); 57 | 58 | reportDir.mkdirs(); 59 | 60 | Object scalaBuffer = Class.forName("scala.collection.JavaConverters") 61 | .getMethod("asScalaBuffer", java.util.List.class) 62 | .invoke(null, new ArrayList<>(sourceDirs)); 63 | Object sourceDirsSeq = scalaBuffer.getClass().getMethod("toIndexedSeq").invoke(scalaBuffer); 64 | 65 | if (coverageOutputCobertura) { 66 | Constructor cst; 67 | try { 68 | cst = CoberturaXmlWriter.class.getConstructor( 69 | Class.forName("scala.collection.immutable.Seq"), 70 | File.class, 71 | Class.forName("scala.Option")); 72 | } catch (NoSuchMethodException | ClassNotFoundException e) { 73 | cst = CoberturaXmlWriter.class.getConstructor( 74 | Class.forName("scala.collection.Seq"), 75 | File.class, 76 | Class.forName("scala.Option")); 77 | } 78 | CoberturaXmlWriter writer = cst.newInstance(sourceDirsSeq, reportDir, new Some<>(sourceEncoding)); 79 | writer.write(coverage); 80 | logger.info("[scoverage] Written Cobertura XML report to " + 81 | reportDir.getAbsolutePath() + 82 | File.separator + 83 | "cobertura.xml"); 84 | } 85 | 86 | if (coverageOutputXML) { 87 | Constructor cst; 88 | try { 89 | cst = ScoverageXmlWriter.class.getConstructor( 90 | Class.forName("scala.collection.immutable.Seq"), 91 | File.class, 92 | boolean.class, 93 | Class.forName("scala.Option")); 94 | } catch (NoSuchMethodException | ClassNotFoundException e) { 95 | cst = ScoverageXmlWriter.class.getConstructor( 96 | Class.forName("scala.collection.Seq"), 97 | File.class, 98 | boolean.class, 99 | Class.forName("scala.Option")); 100 | } 101 | ScoverageXmlWriter writer = cst.newInstance(sourceDirsSeq, reportDir, false, new Some<>(sourceEncoding)); 102 | writer.write(coverage); 103 | logger.info("[scoverage] Written XML report to " + 104 | reportDir.getAbsolutePath() + 105 | File.separator + 106 | Constants.XMLReportFilename()); 107 | if (coverageDebug) { 108 | ScoverageXmlWriter writerDebug = cst.newInstance(sourceDirsSeq, reportDir, true, new Some<>(sourceEncoding)); 109 | writerDebug.write(coverage); 110 | logger.info("[scoverage] Written XML report with debug information to " + 111 | reportDir.getAbsolutePath() + 112 | File.separator + 113 | Constants.XMLReportFilenameWithDebug()); 114 | } 115 | } 116 | 117 | if (coverageOutputHTML) { 118 | Constructor cst; 119 | try { 120 | cst = ScoverageHtmlWriter.class.getConstructor(Class.forName("scala.collection.immutable.Seq"), File.class, Option.class); 121 | } catch (NoSuchMethodException | ClassNotFoundException e) { 122 | cst = ScoverageHtmlWriter.class.getConstructor(Class.forName("scala.collection.Seq"), File.class, Option.class); 123 | } 124 | ScoverageHtmlWriter writer = cst.newInstance(sourceDirsSeq, reportDir, new Some<>(sourceEncoding)); 125 | writer.write(coverage); 126 | logger.info("[scoverage] Written HTML report to " + 127 | reportDir.getAbsolutePath() + 128 | File.separator + 129 | "index.html"); 130 | } 131 | 132 | logger.info("[scoverage] Coverage reports completed"); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaSingleModuleTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import java.util.List; 8 | 9 | public class ScalaSingleModuleTest extends ScoverageFunctionalTest { 10 | 11 | public ScalaSingleModuleTest() { 12 | super("scala-single-module"); 13 | } 14 | 15 | @Override 16 | protected List getVersionAgruments() { 17 | return ScalaVersionArguments.version2; 18 | } 19 | 20 | @Test 21 | public void test() { 22 | 23 | AssertableBuildResult result = dryRun("clean", "test"); 24 | 25 | result.assertTaskDoesntExist(ScoveragePlugin.getCOMPILE_NAME()); 26 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 27 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 28 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 29 | } 30 | 31 | @Test 32 | public void build() { 33 | 34 | AssertableBuildResult result = dryRun("clean", "build"); 35 | 36 | result.assertTaskDoesntExist(ScoveragePlugin.getCOMPILE_NAME()); 37 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 38 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 39 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 40 | } 41 | 42 | @Test 43 | public void reportScoverage() { 44 | 45 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME()); 46 | 47 | result.assertTaskExists(ScoveragePlugin.getCOMPILE_NAME()); 48 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 49 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 50 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 51 | } 52 | 53 | @Test 54 | public void aggregateScoverage() { 55 | 56 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getAGGREGATE_NAME()); 57 | 58 | result.assertNoTasks(); 59 | } 60 | 61 | @Test 62 | public void checkScoverage() throws Exception { 63 | 64 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME()); 65 | 66 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 67 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 68 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 69 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 70 | 71 | assertReportFilesExist(); 72 | assertCoverage(50.0); 73 | } 74 | 75 | @Test 76 | public void checkScoverageFails() throws Exception { 77 | 78 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 79 | "test", "--tests", "org.hello.TestNothingSuite"); 80 | 81 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 82 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 83 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 84 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 85 | 86 | assertReportFilesExist(); 87 | assertCoverage(0.0); 88 | } 89 | 90 | @Test 91 | public void reportScoverageWithExcludedClasses() throws Exception { 92 | 93 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 94 | "-PexcludedFile=.*"); 95 | 96 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 97 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 98 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 99 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 100 | 101 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 102 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 103 | assertCoverage(100.0); // coverage is 100 since no classes are covered 104 | 105 | // compiled class should exist in the default classes directory, but not in scoverage 106 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 107 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 108 | } 109 | 110 | @Test 111 | @Ignore 112 | public void reportScoverageWithoutNormalCompilation() throws Exception { 113 | 114 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 115 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 116 | 117 | result.assertTaskSkipped("compileScala"); 118 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 119 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 120 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 121 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 122 | 123 | assertReportFilesExist(); 124 | assertCoverage(50.0); 125 | 126 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 127 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 128 | } 129 | 130 | @Test 131 | public void reportScoverageWithoutNormalCompilationAndWithExcludedClasses() throws Exception { 132 | 133 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 134 | "-PexcludedFile=.*", "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 135 | 136 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 137 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 138 | assertCoverage(100.0); // coverage is 100 since no classes are covered 139 | 140 | // compiled class should exist in the default classes directory, but not in scoverage 141 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 142 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 143 | } 144 | 145 | protected void assertReportFilesExist() { 146 | 147 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 148 | Assert.assertTrue(resolve(reportDir(), "org/hello/World.scala.html").exists()); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScoverageFunctionalTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import groovy.util.Node; 4 | import groovy.xml.XmlParser; 5 | import org.gradle.testkit.runner.BuildResult; 6 | import org.gradle.testkit.runner.BuildTask; 7 | import org.gradle.testkit.runner.GradleRunner; 8 | import org.gradle.testkit.runner.TaskOutcome; 9 | import org.junit.Assert; 10 | import org.xml.sax.SAXException; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.regex.Pattern; 18 | 19 | import static org.hamcrest.number.IsCloseTo.closeTo; 20 | import static org.junit.Assert.assertThat; 21 | 22 | public abstract class ScoverageFunctionalTest { 23 | 24 | private String projectName; 25 | private GradleRunner runner; 26 | private final XmlParser parser; 27 | 28 | protected ScoverageFunctionalTest(String projectName) { 29 | setProjectName(projectName); 30 | try { 31 | this.parser = new XmlParser(); 32 | parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); 33 | parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 34 | } catch (Exception e) { 35 | throw new RuntimeException(e); 36 | } 37 | } 38 | 39 | protected void setProjectName(String projectName) { 40 | if (projectName != null) { 41 | this.projectName = projectName; 42 | this.runner = GradleRunner.create() 43 | .withProjectDir(projectDir()) 44 | .withPluginClasspath() 45 | .forwardOutput(); 46 | } 47 | } 48 | 49 | protected File projectDir() { 50 | 51 | return new File(getClass().getClassLoader().getResource("projects/" + projectName).getFile()); 52 | } 53 | 54 | protected File buildDir() { 55 | 56 | return buildDir(projectDir()); 57 | } 58 | 59 | protected File buildDir(File projectDir) { 60 | 61 | return projectDir.toPath().resolve("build").toFile(); 62 | } 63 | 64 | protected File reportDir() { 65 | 66 | return reportDir(projectDir()); 67 | } 68 | 69 | protected File reportDir(File projectDir) { 70 | 71 | return buildDir(projectDir).toPath().resolve(ScoveragePlugin.getDEFAULT_REPORT_DIR()).toFile(); 72 | } 73 | 74 | protected AssertableBuildResult run(String... arguments) { 75 | 76 | configureArguments(arguments); 77 | return new AssertableBuildResult(runner.build()); 78 | } 79 | 80 | protected AssertableBuildResult runAndFail(String... arguments) { 81 | 82 | configureArguments(arguments); 83 | return new AssertableBuildResult(runner.buildAndFail()); 84 | } 85 | 86 | protected AssertableBuildResult dryRun(String... arguments) { 87 | 88 | List withDryArgument = new ArrayList<>(Arrays.asList(arguments)); 89 | withDryArgument.add("--dry-run"); 90 | return run(withDryArgument.toArray(new String[]{})); 91 | } 92 | 93 | protected void assertCoverage(Double expected) throws Exception { 94 | 95 | assertCoverage(expected, reportDir()); 96 | } 97 | 98 | protected void assertCoverage(Double expected, File reportDir) throws Exception { 99 | 100 | assertThat(coverage(reportDir, CoverageType.Statement), closeTo(expected, 1.0)); 101 | assertThat(coverage(reportDir, CoverageType.Line), closeTo(expected, 1.0)); 102 | } 103 | 104 | protected File resolve(File file, String relativePath) { 105 | 106 | return file.toPath().resolve(relativePath).toFile(); 107 | } 108 | 109 | private Double coverage(File reportDir, CoverageType coverageType) throws IOException, SAXException, NumberFormatException { 110 | 111 | File reportFile = reportDir.toPath().resolve(coverageType.getFileName()).toFile(); 112 | Node xml = parser.parse(reportFile); 113 | Object attribute = xml.attribute(coverageType.getParamName()); 114 | double rawValue = Double.parseDouble(attribute.toString()); 115 | return coverageType.normalize(rawValue) * 100.0; 116 | } 117 | 118 | protected List getVersionAgruments() { 119 | return ScalaVersionArguments.version2WithLegacyScalatest; 120 | } 121 | 122 | private void configureArguments(String... arguments) { 123 | 124 | List fullArguments = new ArrayList<>(getVersionAgruments()); 125 | 126 | if (Boolean.parseBoolean(System.getProperty("failOnWarning"))) { 127 | fullArguments.add("--warning-mode=fail"); 128 | } else { 129 | fullArguments.add("--warning-mode=all"); 130 | } 131 | fullArguments.addAll(Arrays.asList(arguments)); 132 | 133 | runner.withArguments(fullArguments); 134 | } 135 | 136 | protected static class AssertableBuildResult { 137 | 138 | private final BuildResult result; 139 | 140 | private AssertableBuildResult(BuildResult result) { 141 | 142 | this.result = result; 143 | } 144 | 145 | public BuildResult getResult() { 146 | 147 | return result; 148 | } 149 | 150 | public void assertNoTasks() { 151 | 152 | Assert.assertEquals(0, result.getTasks().size()); 153 | } 154 | 155 | public void assertTaskExists(String taskName) { 156 | 157 | Assert.assertTrue(taskExists(taskName)); 158 | } 159 | 160 | public void assertTaskDoesntExist(String taskName) { 161 | 162 | Assert.assertFalse(taskExists(taskName)); 163 | } 164 | 165 | public void assertTaskSkipped(String taskName) { 166 | 167 | BuildTask task = getTask(taskName); 168 | Assert.assertTrue(task == null || task.getOutcome() == TaskOutcome.SKIPPED); 169 | } 170 | 171 | public void assertTaskSucceeded(String taskName) { 172 | 173 | assertTaskOutcome(taskName, TaskOutcome.SUCCESS); 174 | } 175 | 176 | public void assertTaskFailed(String taskName) { 177 | 178 | assertTaskOutcome(taskName, TaskOutcome.FAILED); 179 | } 180 | 181 | public void assertTaskOutcome(String taskName, TaskOutcome outcome) { 182 | 183 | BuildTask task = getTask(taskName); 184 | Assert.assertNotNull(task); 185 | Assert.assertEquals(outcome, task.getOutcome()); 186 | 187 | } 188 | 189 | private BuildTask getTask(String taskName) { 190 | 191 | return result.task(fullTaskName(taskName)); 192 | } 193 | 194 | private String fullTaskName(String taskName) { 195 | 196 | return ":" + taskName; 197 | } 198 | 199 | private boolean taskExists(String taskName) { 200 | 201 | Pattern regex = Pattern.compile("^(> Task )?" + fullTaskName(taskName), Pattern.MULTILINE); 202 | return regex.matcher(result.getOutput()).find(); 203 | } 204 | } 205 | } 206 | 207 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaSingleModuleWithMultipleTestTasksTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | public class ScalaSingleModuleWithMultipleTestTasksTest extends ScoverageFunctionalTest { 8 | public ScalaSingleModuleWithMultipleTestTasksTest() { 9 | super("scala-single-module-multiple-test-tasks"); 10 | } 11 | 12 | @Test 13 | public void test() { 14 | 15 | AssertableBuildResult result = dryRun("clean", "test"); 16 | 17 | result.assertTaskDoesntExist(ScoveragePlugin.getCOMPILE_NAME()); 18 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 19 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 20 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 21 | } 22 | 23 | @Test 24 | public void build() { 25 | 26 | AssertableBuildResult result = dryRun("clean", "build"); 27 | 28 | result.assertTaskDoesntExist(ScoveragePlugin.getCOMPILE_NAME()); 29 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 30 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 31 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 32 | } 33 | 34 | @Test 35 | public void reportScoverage() { 36 | 37 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME()); 38 | 39 | result.assertTaskExists(ScoveragePlugin.getCOMPILE_NAME()); 40 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 41 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 42 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 43 | } 44 | 45 | @Test 46 | public void aggregateScoverage() { 47 | 48 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getAGGREGATE_NAME()); 49 | 50 | result.assertNoTasks(); 51 | } 52 | 53 | 54 | @Test 55 | public void checkScoverage() throws Exception { 56 | 57 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME()); 58 | 59 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 60 | result.assertTaskSucceeded("reportTestScoverage"); 61 | result.assertTaskSucceeded("reportIntTestScoverage"); 62 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 63 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 64 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 65 | 66 | assertReportFilesExist(); 67 | assertCoverage(100.0); 68 | } 69 | 70 | @Test 71 | public void checkScoverageIntTest() throws Exception { 72 | AssertableBuildResult result = runAndFail("clean", "-x", "reportTestScoverage", ScoveragePlugin.getCHECK_NAME()); 73 | 74 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 75 | result.assertTaskDoesntExist("reportTestScoverage"); 76 | result.assertTaskSucceeded("reportIntTestScoverage"); 77 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 78 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 79 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 80 | 81 | assertReportFilesExist(); 82 | assertCoverage(50.0); 83 | } 84 | 85 | 86 | @Test 87 | public void checkScoverageFails() throws Exception { 88 | 89 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 90 | "intTest", "--tests", "org.hello.TestNothingSuite", 91 | "-x", "test"); 92 | 93 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 94 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 95 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 96 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 97 | 98 | assertReportFilesExist(); 99 | assertCoverage(0.0); 100 | } 101 | 102 | @Test 103 | public void reportScoverageWithExcludedClasses() throws Exception { 104 | 105 | AssertableBuildResult result = run("clean", "-PexcludedFile=.*", ScoveragePlugin.getREPORT_NAME()); 106 | 107 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 108 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 109 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 110 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 111 | 112 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 113 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 114 | assertCoverage(100.0); // coverage is 100 since no classes are covered 115 | 116 | // compiled class should exist in the default classes directory, but not in scoverage 117 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 118 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 119 | } 120 | 121 | @Test 122 | @Ignore 123 | public void reportScoverageWithoutNormalCompilation() throws Exception { 124 | 125 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 126 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 127 | 128 | result.assertTaskSkipped("compileScala"); 129 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 130 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 131 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 132 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 133 | 134 | assertReportFilesExist(); 135 | assertCoverage(100.0); 136 | 137 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 138 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 139 | } 140 | 141 | @Test 142 | public void reportScoverageWithoutNormalCompilationAndWithExcludedClasses() throws Exception { 143 | 144 | AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(), 145 | "-PexcludedFile=.*", "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 146 | 147 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 148 | Assert.assertFalse(resolve(reportDir(), "org/hello/World.scala.html").exists()); 149 | assertCoverage(100.0); // coverage is 100 since no classes are covered 150 | 151 | // compiled class should exist in the default classes directory, but not in scoverage 152 | Assert.assertTrue(resolve(buildDir(), "classes/scala/main/org/hello/World.class").exists()); 153 | Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists()); 154 | } 155 | 156 | 157 | private void assertReportFilesExist() { 158 | 159 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 160 | Assert.assertTrue(resolve(reportDir(), "org/hello/World.scala.html").exists()); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Java CI with Gradle](https://github.com/scoverage/gradle-scoverage/actions/workflows/gradle.yml/badge.svg)](https://github.com/scoverage/gradle-scoverage/actions/workflows/gradle.yml) 2 | 3 | gradle-scoverage 4 | ================ 5 | A plugin to enable the use of Scoverage in a gradle Scala project. 6 | 7 | Usage 8 | ----- 9 | 10 | You can find instructions on how to apply the plugin at http://plugins.gradle.org/plugin/org.scoverage 11 | 12 | ### Available tasks 13 | 14 | 1. `reportScoverage`: Produces XML and HTML reports for analysing test code coverage. 15 | 16 | The plugin automatically creates a `report{Task name}Scoverage` task for each test task in your 17 | Gradle build. The `reportScoverage` task will run all test tasks and you can use the individual 18 | tasks to run only the desired tests. For example, to run only the unit tests and no other test 19 | tasks (e.g., integration tests), you can run `reportTestScoverage`. 20 | 21 | 2. `aggregateScoverage`: Aggregates coverage statistics in composite builds. 22 | 23 | When applied on a project with sub-projects, the plugin will create the aggregation task `aggregateScoverage`, which 24 | will first generate reports for each project individually (including the parent project), and will then generate an 25 | aggregated result based on these reports. 26 | 27 | The plugin must be applied on a sub-project for it to be included in the aggregated; applying the plugin on a 28 | project _does not_ automatically apply it on sub-projects. 29 | 30 | The aggregated report will override the parent-project specific report (`parent-project/build/reports/scoverage`). 31 | 32 | One can still use `reportScoverage` in order to generate a report without aggregation. 33 | 34 | 3. `checkScoverage`: Validates coverage status according to generated reports (aggregated or not). 35 | 36 | `gradle checkScoverage` will automatically invoke `reportScoverage` but it won't generate aggregated reports. 37 | In order to check coverage of aggregated reports one should use `gradle checkScoverage aggregateScoverage`. 38 | 39 | **Note:** The plugin is not compatible with composite builds. For more information, see [the relevant issue](https://github.com/scoverage/gradle-scoverage/issues/98). 40 | 41 | ### Configuration 42 | 43 | The plugin exposes multiple options that can be configured by setting them in an `scoverage` block within the project's 44 | build script. These options are as follows: 45 | 46 | * `scoverageVersion = ` (default `"2.1.1`): The version of the scoverage scalac plugin. This (gradle) plugin 47 | should be compatible with all 1+ versions. 48 | 49 | * `scoverageScalaVersion = ` (default `detected`): The scala version of the scoverage scalac plugin. This 50 | overrides the version of the `scala-library` compile dependency (if the dependency is configured). 51 | 52 | * `coverageOutputCobertura = ` (default `true`): Enables/disables cobertura.xml file generation (for both aggregated and non-aggregated reports). 53 | 54 | * `coverageOutputXML = ` (default `true`): Enables/disables scoverage XML output (for both aggregated and non-aggregated reports). 55 | 56 | * `coverageOutputHTML = ` (default `true`): Enables/disables scoverage HTML output (for both aggregated and non-aggregated reports). 57 | 58 | * `coverageDebug = ` (default `false`): Enables/disables scoverage debug output (for both aggregated and non-aggregated reports). 59 | 60 | * `minimumRate = ` (default `0.75`): The minimum amount of coverage in decimal proportion (`1.0` == 100%) 61 | required for the validation to pass (otherwise `checkScoverage` will fail the build). 62 | 63 | * `coverageType = ` (default `CoverageType.Statement`): The type of coverage validated by the 64 | `checkScoverage` task. For more information on the different types, please refer to the documentation of the scalac 65 | plugin (https://github.com/scoverage/scalac-scoverage-plugin). 66 | 67 | * `excludedFiles = ` (default `not set`): Comma separated list of regexes for files to exclude from coverage. 68 | 69 | * `excludedPackages = ` (default `not set`): Comma separated list of regexes for packages, classes and modules to exclude from coverage. 70 | 71 | #### Multiple check tasks 72 | 73 | It is possible to configure multiple checks; for instance, one check for a statement rate and another for a branch rate: 74 | ``` 75 | scoverage { 76 | check { 77 | minimumRate = 0.5 78 | coverageType = CoverageType.Statement 79 | } 80 | check { 81 | minimumRate = 0.8 82 | coverageType = CoverageType.Branch 83 | } 84 | } 85 | ``` 86 | 87 | Note that you cannot mix multiple-checks syntax with plain check configuration: 88 | ``` 89 | // ok 90 | scoverage { 91 | check { 92 | minimumRate = 0.5 93 | coverageType = CoverageType.Statement 94 | } 95 | } 96 | 97 | // ok 98 | scoverage { 99 | minimumRate = 0.2 100 | } 101 | 102 | // NOT ok 103 | scoverage { 104 | minimumRate = 0.2 105 | check { 106 | minimumRate = 0.5 107 | coverageType = CoverageType.Statement 108 | } 109 | } 110 | ``` 111 | 112 | In case you use the Kotlin DSL, the following snippet can give you pointers for configuring Scoverage: 113 | ```kotlin 114 | scoverage { 115 | minimumRate.set(BigDecimal("0.80")) 116 | excludedPackages.set(listOf("com.example.scala.demo")) 117 | } 118 | ``` 119 | 120 | ### Compatibility with Consistent Versions Plugin 121 | 122 | In order for the plugin to work alongside [Palantir's consistent versions plugin](https://github.com/palantir/gradle-consistent-versions), 123 | the Scala version must be manually configured (via `scoverageScalaVersion`); otherwise, the plugin will attempt to 124 | resolve the compilation classpath, which is prohibited by the versions plugin. 125 | 126 | Migration to 8.x 127 | ---------------- 128 | 129 | * Requires scoverage 2.0 130 | * Adds support for Scala 3 131 | * Drops support for disabling normal compilation 132 | 133 | Migration to 7.x 134 | ---------------- 135 | 136 | * Running without normal compilation is now made with `-PscoverageCompileOnly` instead of `-x compileScala`. 137 | 138 | Migration to 5.x 139 | ---------------- 140 | 141 | * Requires scoverage 1.4.2 or higher (and uses this version by default) 142 | * Adds support for Scala 2.13 143 | * Drops support for Scala 2.11 144 | 145 | Migration to 4.x 146 | ---------------- 147 | 148 | * Requires scoverage 1.4.1 or higher (and uses this version by default) 149 | * Requires application of the plugin to appropriate subprojects. A multi-module project might apply it to all. 150 | 151 | ```groovy 152 | plugins { 153 | id 'org.scoverage' version '4.0.0' 154 | } 155 | subprojects { 156 | apply plugin: 'org.scoverage' 157 | } 158 | ``` 159 | 160 | Migration to 3.x 161 | ---------------- 162 | 163 | * No more `testScoverage` task; instead, `test` will run coverage whenever the build is invoked with any of the scoverage tasks. 164 | 165 | * No more need to declare scalac dependencies: 166 | ```groovy 167 | // can safely delete this from build scripts 168 | dependencies { 169 | scoverage group: 'org.scoverage', name: 'scalac-scoverage-plugin_2.12', version: '1.3.1' 170 | scoverage group: 'org.scoverage', name: 'scalac-scoverage-runtime_2.12', version: '1.3.1' 171 | } 172 | ``` 173 | 174 | * All configurations are configured in `scoverage` block. For instance: 175 | ```groovy 176 | // do this 177 | scoverage { 178 | minimumRate = 0.5 179 | } 180 | 181 | // instead of this 182 | checkScoverage { 183 | minimumRate = 0.5 184 | } 185 | ``` 186 | 187 | * No more need to declare aggregation task: 188 | ```groovy 189 | // can safely delete this from build scripts 190 | task aggregateScoverage(type: org.scoverage.ScoverageAggregate) 191 | checkScoverage { 192 | reportDir = file("$buildDir/scoverage-aggregate") 193 | } 194 | ``` 195 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaMultiModuleWithMultipleTestTasksTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | 8 | import java.io.File; 9 | 10 | 11 | public class ScalaMultiModuleWithMultipleTestTasksTest extends ScoverageFunctionalTest { 12 | 13 | 14 | public ScalaMultiModuleWithMultipleTestTasksTest() { 15 | super("scala-multi-module-multiple-test-tasks"); 16 | } 17 | 18 | @Test 19 | public void reportScoverage() { 20 | 21 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME()); 22 | 23 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 24 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 25 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 26 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 27 | result.assertTaskExists("intTest"); 28 | result.assertTaskExists("reportIntTestScoverage"); 29 | result.assertTaskExists("a:intTest"); 30 | result.assertTaskExists("b:intTest"); 31 | result.assertTaskExists("common:intTest"); 32 | result.assertTaskExists("a:reportIntTestScoverage"); 33 | result.assertTaskExists("b:reportIntTestScoverage"); 34 | result.assertTaskExists("common:reportIntTestScoverage"); 35 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 36 | } 37 | 38 | @Test 39 | public void reportScoverageOnlyRoot() { 40 | 41 | AssertableBuildResult result = dryRun("clean", ":" + ScoveragePlugin.getREPORT_NAME()); 42 | 43 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 44 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getREPORT_NAME()); 45 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 46 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 47 | } 48 | 49 | @Test 50 | public void reportScoverageOnlyA() { 51 | 52 | AssertableBuildResult result = dryRun("clean", ":a:" + ScoveragePlugin.getREPORT_NAME()); 53 | 54 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 55 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 56 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 57 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 58 | } 59 | 60 | @Test 61 | public void aggregateScoverage() { 62 | 63 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getAGGREGATE_NAME()); 64 | 65 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 66 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 67 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 68 | result.assertTaskExists(ScoveragePlugin.getAGGREGATE_NAME()); 69 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 70 | } 71 | 72 | @Test 73 | public void checkScoverage() { 74 | 75 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getCHECK_NAME()); 76 | 77 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 78 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 79 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 80 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 81 | result.assertTaskExists(ScoveragePlugin.getCHECK_NAME()); 82 | result.assertTaskExists("a:" + ScoveragePlugin.getCHECK_NAME()); 83 | result.assertTaskExists("b:" + ScoveragePlugin.getCHECK_NAME()); 84 | result.assertTaskExists("common:" + ScoveragePlugin.getCHECK_NAME()); 85 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 86 | } 87 | 88 | @Test 89 | public void checkScoverageOnlyRoot() { 90 | 91 | AssertableBuildResult result = dryRun("clean", ":" + ScoveragePlugin.getCHECK_NAME()); 92 | 93 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 94 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getREPORT_NAME()); 95 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 96 | result.assertTaskExists(ScoveragePlugin.getCHECK_NAME()); 97 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getCHECK_NAME()); 98 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getCHECK_NAME()); 99 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 100 | } 101 | 102 | @Test 103 | public void checkScoverageOnlyA() { 104 | 105 | AssertableBuildResult result = dryRun("clean", ":a:" + ScoveragePlugin.getCHECK_NAME()); 106 | 107 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 108 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 109 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 110 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 111 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 112 | result.assertTaskExists("a:" + ScoveragePlugin.getCHECK_NAME()); 113 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getCHECK_NAME()); 114 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getCHECK_NAME()); 115 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 116 | } 117 | 118 | @Test 119 | public void checkScoverageWithoutIntTests() { 120 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getCHECK_NAME(), 121 | "-x", "intTest"); 122 | 123 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 124 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 125 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 126 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 127 | result.assertTaskDoesntExist("intTest"); 128 | result.assertTaskExists("reportIntTestScoverage"); 129 | result.assertTaskDoesntExist("a:intTest"); 130 | result.assertTaskDoesntExist("b:intTest"); 131 | result.assertTaskDoesntExist("common:intTest"); 132 | result.assertTaskExists("a:reportIntTestScoverage"); 133 | result.assertTaskExists("b:reportIntTestScoverage"); 134 | result.assertTaskExists("common:reportIntTestScoverage"); 135 | } 136 | 137 | @Test 138 | public void checkAndAggregateScoverage() throws Exception { 139 | 140 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 141 | ScoveragePlugin.getAGGREGATE_NAME()); 142 | 143 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 144 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 145 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 146 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 147 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 148 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCHECK_NAME()); 149 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCHECK_NAME()); 150 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCHECK_NAME()); 151 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 152 | 153 | assertAllReportFilesExist(); 154 | assertCoverage(100.0); 155 | } 156 | 157 | @Test 158 | public void checkScoverageWithoutCoverageInRoot() throws Exception { 159 | 160 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 161 | "test", 162 | "--tests", "org.hello.TestNothingSuite", 163 | "--tests", "org.hello.a.WorldASuite", 164 | "--tests", "org.hello.b.WorldBSuite", 165 | "--tests", "org.hello.common.WorldCommonSuite", 166 | "-x", "intTest"); 167 | 168 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 169 | 170 | assertRootReportFilesExist(); 171 | assertCoverage(0.0); 172 | } 173 | 174 | @Test 175 | public void checkScoverageWithoutCoverageInA() throws Exception { 176 | 177 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 178 | "test", 179 | "--tests", "org.hello.a.TestNothingASuite", 180 | "--tests", "org.hello.WorldSuite", 181 | "--tests", "org.hello.b.WorldBSuite", 182 | "--tests", "org.hello.common.WorldCommonSuite", 183 | "-x", ":a:intTest"); 184 | 185 | result.assertTaskFailed("a:" + ScoveragePlugin.getCHECK_NAME()); 186 | 187 | assertAReportFilesExist(); 188 | assertCoverage(0.0, reportDir(projectDir().toPath().resolve("a").toFile())); 189 | } 190 | 191 | @Test 192 | @Ignore 193 | public void checkScoverageWithoutNormalCompilationAndWithoutCoverageInCommon() throws Exception { 194 | 195 | AssertableBuildResult result = runAndFail("clean", 196 | ":a:test", 197 | ":common:test", "--tests", "org.hello.common.TestNothingCommonSuite", 198 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY(), 199 | ScoveragePlugin.getCHECK_NAME()); 200 | 201 | result.assertTaskFailed("common:" + ScoveragePlugin.getCHECK_NAME()); 202 | 203 | assertCommonReportFilesExist(); 204 | assertCoverage(0.0, reportDir(projectDir().toPath().resolve("common").toFile())); 205 | } 206 | 207 | @Test 208 | public void checkAndAggregateScoverageWithoutCoverageInRoot() throws Exception { 209 | 210 | // should pass as the check on the root is for the aggregation (which covers > 50%) 211 | 212 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 213 | ScoveragePlugin.getAGGREGATE_NAME(), "test", 214 | "--tests", "org.hello.TestNothingSuite", 215 | "--tests", "org.hello.a.WorldASuite", 216 | "--tests", "org.hello.b.WorldBSuite", 217 | "--tests", "org.hello.common.WorldCommonSuite"); 218 | 219 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 220 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 221 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 222 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 223 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 224 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCHECK_NAME()); 225 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCHECK_NAME()); 226 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCHECK_NAME()); 227 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 228 | 229 | assertAllReportFilesExist(); 230 | assertCoverage(93.33); 231 | } 232 | 233 | @Test 234 | public void checkAndAggregateScoverageWithoutCoverageInAll() throws Exception { 235 | 236 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 237 | ScoveragePlugin.getAGGREGATE_NAME(), "test", 238 | "--tests", "org.hello.TestNothingSuite", 239 | "--tests", "org.hello.a.TestNothingASuite", 240 | "--tests", "org.hello.b.TestNothingBSuite", 241 | "--tests", "org.hello.common.TestNothingCommonSuite", 242 | "-x", "intTest"); 243 | 244 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 245 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 246 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 247 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 248 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 249 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 250 | 251 | assertAllReportFilesExist(); 252 | assertCoverage(0.0); 253 | } 254 | 255 | @Test 256 | @Ignore 257 | public void aggregateScoverageWithoutNormalCompilation() throws Exception { 258 | 259 | AssertableBuildResult result = run("clean", ScoveragePlugin.getAGGREGATE_NAME(), 260 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 261 | 262 | result.assertTaskSkipped("compileScala"); 263 | result.assertTaskSkipped("a:compileScala"); 264 | result.assertTaskSkipped("b:compileScala"); 265 | result.assertTaskSkipped("common:compileScala"); 266 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 267 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCOMPILE_NAME()); 268 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCOMPILE_NAME()); 269 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCOMPILE_NAME()); 270 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 271 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 272 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 273 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 274 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 275 | 276 | assertAllReportFilesExist(); 277 | assertCoverage(100.0); 278 | 279 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/main/org/hello/a/WorldA.class").exists()); 280 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/scoverage/org/hello/a/WorldA.class").exists()); 281 | 282 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "b")), "classes/scala/main/org/hello/b/WorldB.class").exists()); 283 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "b")), "classes/scala/scoverage/org/hello/b/WorldB.class").exists()); 284 | 285 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/main/org/hello/common/WorldCommon.class").exists()); 286 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/scoverage/org/hello/common/WorldCommon.class").exists()); 287 | } 288 | 289 | private void assertAllReportFilesExist() { 290 | 291 | assertRootReportFilesExist(); 292 | assertAReportFilesExist(); 293 | assertBReportFilesExist(); 294 | assertCommonReportFilesExist(); 295 | assertAggregationFilesExist(); 296 | } 297 | 298 | private void assertAggregationFilesExist() { 299 | 300 | Assert.assertTrue(resolve(reportDir(), "org/hello/a/WorldA.scala.html").exists()); 301 | Assert.assertTrue(resolve(reportDir(), "org/hello/b/WorldB.scala.html").exists()); 302 | Assert.assertTrue(resolve(reportDir(), "org/hello/common/WorldCommon.scala.html").exists()); 303 | } 304 | 305 | private void assertRootReportFilesExist() { 306 | 307 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 308 | Assert.assertTrue(resolve(reportDir(), "org/hello/World.scala.html").exists()); 309 | } 310 | 311 | private void assertAReportFilesExist() { 312 | 313 | File reportDir = reportDir(projectDir().toPath().resolve("a").toFile()); 314 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 315 | Assert.assertTrue(resolve(reportDir, "org/hello/a/WorldA.scala.html").exists()); 316 | } 317 | 318 | private void assertBReportFilesExist() { 319 | 320 | File reportDir = reportDir(projectDir().toPath().resolve("b").toFile()); 321 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 322 | Assert.assertTrue(resolve(reportDir, "org/hello/b/WorldB.scala.html").exists()); 323 | } 324 | 325 | private void assertCommonReportFilesExist() { 326 | 327 | File reportDir = reportDir(projectDir().toPath().resolve("common").toFile()); 328 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 329 | Assert.assertTrue(resolve(reportDir, "org/hello/common/WorldCommon.scala.html").exists()); 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /src/functionalTest/java/org/scoverage/ScalaMultiModuleTest.java: -------------------------------------------------------------------------------- 1 | package org.scoverage; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | 9 | public class ScalaMultiModuleTest extends ScoverageFunctionalTest { 10 | 11 | public ScalaMultiModuleTest() { 12 | super("scala-multi-module"); 13 | } 14 | 15 | @Test 16 | public void reportScoverage() { 17 | 18 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME()); 19 | 20 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 21 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 22 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 23 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 24 | } 25 | 26 | @Test 27 | public void reportScoverageParallel() { 28 | 29 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getREPORT_NAME(), "--parallel"); 30 | 31 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 32 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 33 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 34 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 35 | } 36 | 37 | @Test 38 | public void reportScoverageOnlyRoot() { 39 | 40 | AssertableBuildResult result = dryRun("clean", ":" + ScoveragePlugin.getREPORT_NAME()); 41 | 42 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 43 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getREPORT_NAME()); 44 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 45 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 46 | } 47 | 48 | @Test 49 | public void reportScoverageOnlyA() { 50 | 51 | AssertableBuildResult result = run("clean", ":a:" + ScoveragePlugin.getREPORT_NAME()); 52 | 53 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 54 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 55 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 56 | 57 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCOMPILE_NAME()); 58 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 59 | 60 | assertAReportFilesExist(); 61 | } 62 | 63 | @Test 64 | @Ignore 65 | public void reportScoverageOnlyAWithoutNormalCompilation() { 66 | 67 | AssertableBuildResult result = run("clean", ":a:" + ScoveragePlugin.getREPORT_NAME(), 68 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 69 | 70 | result.assertTaskSkipped("compileScala"); 71 | result.assertTaskSkipped("a:compileScala"); 72 | result.assertTaskSkipped("common:compileScala"); 73 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCOMPILE_NAME()); 74 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCOMPILE_NAME()); 75 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 76 | 77 | assertAReportFilesExist(); 78 | 79 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/main/org/hello/a/WorldA.class").exists()); 80 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/scoverage/org/hello/a/WorldA.class").exists()); 81 | 82 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/main/org/hello/common/WorldCommon.class").exists()); 83 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/scoverage/org/hello/common/WorldCommon.class").exists()); 84 | } 85 | 86 | @Test 87 | public void aggregateScoverage() { 88 | 89 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getAGGREGATE_NAME()); 90 | 91 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 92 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 93 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 94 | result.assertTaskExists(ScoveragePlugin.getAGGREGATE_NAME()); 95 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 96 | } 97 | 98 | @Test 99 | public void checkScoverage() { 100 | 101 | AssertableBuildResult result = dryRun("clean", ScoveragePlugin.getCHECK_NAME()); 102 | 103 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 104 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 105 | result.assertTaskExists("b:" + ScoveragePlugin.getREPORT_NAME()); 106 | result.assertTaskExists("common:" + ScoveragePlugin.getREPORT_NAME()); 107 | result.assertTaskExists(ScoveragePlugin.getCHECK_NAME()); 108 | result.assertTaskExists("a:" + ScoveragePlugin.getCHECK_NAME()); 109 | result.assertTaskExists("b:" + ScoveragePlugin.getCHECK_NAME()); 110 | result.assertTaskExists("common:" + ScoveragePlugin.getCHECK_NAME()); 111 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 112 | } 113 | 114 | @Test 115 | public void checkScoverageOnlyRoot() { 116 | 117 | AssertableBuildResult result = dryRun("clean", ":" + ScoveragePlugin.getCHECK_NAME()); 118 | 119 | result.assertTaskExists(ScoveragePlugin.getREPORT_NAME()); 120 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getREPORT_NAME()); 121 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 122 | result.assertTaskExists(ScoveragePlugin.getCHECK_NAME()); 123 | result.assertTaskDoesntExist("a:" + ScoveragePlugin.getCHECK_NAME()); 124 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getCHECK_NAME()); 125 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 126 | } 127 | 128 | @Test 129 | public void checkScoverageOnlyA() { 130 | 131 | AssertableBuildResult result = dryRun("clean", ":a:" + ScoveragePlugin.getCHECK_NAME()); 132 | 133 | result.assertTaskDoesntExist(ScoveragePlugin.getREPORT_NAME()); 134 | result.assertTaskExists("a:" + ScoveragePlugin.getREPORT_NAME()); 135 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getREPORT_NAME()); 136 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getREPORT_NAME()); 137 | result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME()); 138 | result.assertTaskExists("a:" + ScoveragePlugin.getCHECK_NAME()); 139 | result.assertTaskDoesntExist("b:" + ScoveragePlugin.getCHECK_NAME()); 140 | result.assertTaskDoesntExist("common:" + ScoveragePlugin.getCHECK_NAME()); 141 | result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME()); 142 | } 143 | 144 | @Test 145 | public void checkAndAggregateScoverage() throws Exception { 146 | 147 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 148 | ScoveragePlugin.getAGGREGATE_NAME()); 149 | 150 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 151 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 152 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 153 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 154 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 155 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCHECK_NAME()); 156 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCHECK_NAME()); 157 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCHECK_NAME()); 158 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 159 | 160 | assertAllReportFilesExist(); 161 | assertCoverage(100.0); 162 | } 163 | 164 | @Test 165 | public void checkScoverageWithoutCoverageInRoot() throws Exception { 166 | 167 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 168 | "test", 169 | "--tests", "org.hello.TestNothingSuite", 170 | "--tests", "org.hello.a.WorldASuite", 171 | "--tests", "org.hello.b.WorldBSuite", 172 | "--tests", "org.hello.common.WorldCommonSuite"); 173 | 174 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 175 | 176 | assertRootReportFilesExist(); 177 | assertCoverage(0.0); 178 | } 179 | 180 | @Test 181 | public void checkScoverageWithoutCoverageInA() throws Exception { 182 | 183 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 184 | "test", 185 | "--tests", "org.hello.a.TestNothingASuite", 186 | "--tests", "org.hello.WorldSuite", 187 | "--tests", "org.hello.b.WorldBSuite", 188 | "--tests", "org.hello.common.WorldCommonSuite"); 189 | 190 | result.assertTaskFailed("a:" + ScoveragePlugin.getCHECK_NAME()); 191 | 192 | assertAReportFilesExist(); 193 | assertCoverage(0.0, reportDir(projectDir().toPath().resolve("a").toFile())); 194 | } 195 | 196 | @Test 197 | @Ignore 198 | public void checkScoverageWithoutNormalCompilationAndWithoutCoverageInCommon() throws Exception { 199 | 200 | AssertableBuildResult result = runAndFail("clean", 201 | ":a:test", 202 | ":common:test", "--tests", "org.hello.common.TestNothingCommonSuite", 203 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY(), 204 | ScoveragePlugin.getCHECK_NAME()); 205 | 206 | result.assertTaskFailed("common:" + ScoveragePlugin.getCHECK_NAME()); 207 | 208 | assertCommonReportFilesExist(); 209 | assertCoverage(0.0, reportDir(projectDir().toPath().resolve("common").toFile())); 210 | } 211 | 212 | @Test 213 | public void checkAndAggregateScoverageWithoutCoverageInRoot() throws Exception { 214 | 215 | // should pass as the check on the root is for the aggregation (which covers > 50%) 216 | 217 | AssertableBuildResult result = run("clean", ScoveragePlugin.getCHECK_NAME(), 218 | ScoveragePlugin.getAGGREGATE_NAME(), "test", 219 | "--tests", "org.hello.TestNothingSuite", 220 | "--tests", "org.hello.a.WorldASuite", 221 | "--tests", "org.hello.b.WorldBSuite", 222 | "--tests", "org.hello.common.WorldCommonSuite"); 223 | 224 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 225 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 226 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 227 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 228 | result.assertTaskSucceeded(ScoveragePlugin.getCHECK_NAME()); 229 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCHECK_NAME()); 230 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCHECK_NAME()); 231 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCHECK_NAME()); 232 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 233 | 234 | assertAllReportFilesExist(); 235 | assertCoverage(87.5); 236 | } 237 | 238 | @Test 239 | public void checkAndAggregateScoverageWithoutCoverageInAll() throws Exception { 240 | 241 | AssertableBuildResult result = runAndFail("clean", ScoveragePlugin.getCHECK_NAME(), 242 | ScoveragePlugin.getAGGREGATE_NAME(), "test", 243 | "--tests", "org.hello.TestNothingSuite", 244 | "--tests", "org.hello.a.TestNothingASuite", 245 | "--tests", "org.hello.b.TestNothingBSuite", 246 | "--tests", "org.hello.common.TestNothingCommonSuite"); 247 | 248 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 249 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 250 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 251 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 252 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 253 | result.assertTaskFailed(ScoveragePlugin.getCHECK_NAME()); 254 | 255 | assertAllReportFilesExist(); 256 | assertCoverage(0.0); 257 | } 258 | 259 | @Test 260 | @Ignore 261 | public void aggregateScoverageWithoutNormalCompilation() throws Exception { 262 | 263 | AssertableBuildResult result = run("clean", ScoveragePlugin.getAGGREGATE_NAME(), 264 | "-P" + ScoveragePlugin.getSCOVERAGE_COMPILE_ONLY_PROPERTY()); 265 | 266 | result.assertTaskSkipped("compileScala"); 267 | result.assertTaskSkipped("a:compileScala"); 268 | result.assertTaskSkipped("b:compileScala"); 269 | result.assertTaskSkipped("common:compileScala"); 270 | result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME()); 271 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getCOMPILE_NAME()); 272 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getCOMPILE_NAME()); 273 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getCOMPILE_NAME()); 274 | result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME()); 275 | result.assertTaskSucceeded("a:" + ScoveragePlugin.getREPORT_NAME()); 276 | result.assertTaskSucceeded("b:" + ScoveragePlugin.getREPORT_NAME()); 277 | result.assertTaskSucceeded("common:" + ScoveragePlugin.getREPORT_NAME()); 278 | result.assertTaskSucceeded(ScoveragePlugin.getAGGREGATE_NAME()); 279 | 280 | assertAllReportFilesExist(); 281 | assertCoverage(100.0); 282 | 283 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/main/org/hello/a/WorldA.class").exists()); 284 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "a")), "classes/scala/scoverage/org/hello/a/WorldA.class").exists()); 285 | 286 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "b")), "classes/scala/main/org/hello/b/WorldB.class").exists()); 287 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "b")), "classes/scala/scoverage/org/hello/b/WorldB.class").exists()); 288 | 289 | Assert.assertTrue(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/main/org/hello/common/WorldCommon.class").exists()); 290 | Assert.assertFalse(resolve(buildDir(resolve(projectDir(), "common")), "classes/scala/scoverage/org/hello/common/WorldCommon.class").exists()); 291 | } 292 | 293 | private void assertAllReportFilesExist() { 294 | 295 | assertRootReportFilesExist(); 296 | assertAReportFilesExist(); 297 | assertBReportFilesExist(); 298 | assertCommonReportFilesExist(); 299 | assertAggregationFilesExist(); 300 | } 301 | 302 | private void assertAggregationFilesExist() { 303 | 304 | Assert.assertTrue(resolve(reportDir(), "org/hello/a/WorldA.scala.html").exists()); 305 | Assert.assertTrue(resolve(reportDir(), "org/hello/b/WorldB.scala.html").exists()); 306 | Assert.assertTrue(resolve(reportDir(), "org/hello/common/WorldCommon.scala.html").exists()); 307 | } 308 | 309 | private void assertRootReportFilesExist() { 310 | 311 | Assert.assertTrue(resolve(reportDir(), "index.html").exists()); 312 | Assert.assertTrue(resolve(reportDir(), "org/hello/World.scala.html").exists()); 313 | } 314 | 315 | private void assertAReportFilesExist() { 316 | 317 | File reportDir = reportDir(projectDir().toPath().resolve("a").toFile()); 318 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 319 | Assert.assertTrue(resolve(reportDir, "org/hello/a/WorldA.scala.html").exists()); 320 | } 321 | 322 | private void assertBReportFilesExist() { 323 | 324 | File reportDir = reportDir(projectDir().toPath().resolve("b").toFile()); 325 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 326 | Assert.assertTrue(resolve(reportDir, "org/hello/b/WorldB.scala.html").exists()); 327 | } 328 | 329 | private void assertCommonReportFilesExist() { 330 | 331 | File reportDir = reportDir(projectDir().toPath().resolve("common").toFile()); 332 | Assert.assertTrue(resolve(reportDir, "index.html").exists()); 333 | Assert.assertTrue(resolve(reportDir, "org/hello/common/WorldCommon.scala.html").exists()); 334 | } 335 | } 336 | --------------------------------------------------------------------------------