diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9c15bf2b..531f3394 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -224,9 +224,6 @@ workflows:
- run:
name: Unit testing
command: sbt test
- - run:
- name: It testing
- command: sbt it:test
- run:
name: Aggregate coverage reports
command: sbt coverageAggregate
diff --git a/api-scala/src/main/scala/com/codacy/api/CoverageReport.scala b/api-scala/src/main/scala/com/codacy/api/CoverageReport.scala
new file mode 100644
index 00000000..f4e66419
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/CoverageReport.scala
@@ -0,0 +1,21 @@
+package com.codacy.api
+
+import play.api.libs.json.{JsNumber, JsObject, Json, Writes}
+
+case class CoverageFileReport(filename: String, coverage: Map[Int, Int])
+
+case class CoverageReport(fileReports: Seq[CoverageFileReport])
+
+object CoverageReport {
+ implicit val mapWrites: Writes[Map[Int, Int]] = Writes[Map[Int, Int]] { map: Map[Int, Int] =>
+ JsObject(map.map {
+ case (key, value) => (key.toString, JsNumber(value))
+ }(collection.breakOut))
+ }
+ implicit val coverageFileReportWrites: Writes[CoverageFileReport] = Json.writes[CoverageFileReport]
+ implicit val coverageReportWrites: Writes[CoverageReport] = Json.writes[CoverageReport]
+}
+
+object OrganizationProvider extends Enumeration {
+ val manual, gh, bb, ghe, bbe, gl, gle = Value
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala
new file mode 100644
index 00000000..f971657b
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/client/CodacyClient.scala
@@ -0,0 +1,109 @@
+package com.codacy.api.client
+
+import play.api.libs.json._
+import com.codacy.api.util.JsonOps
+import scalaj.http.Http
+
+import java.net.URL
+import scala.util.{Failure, Success, Try}
+import scala.util.control.NonFatal
+
+class CodacyClient(
+ apiUrl: Option[String] = None,
+ apiToken: Option[String] = None,
+ projectToken: Option[String] = None
+) {
+
+ private case class ErrorJson(error: String)
+ private case class PaginatedResult[T](next: Option[String], values: Seq[T])
+
+ private implicit val errorJsonFormat: Reads[ErrorJson] = Json.reads[ErrorJson]
+
+ private val tokens = Map.empty[String, String] ++
+ apiToken.map(t => "api-token" -> t) ++
+ projectToken.map(t => "project-token" -> t) ++
+ // This is deprecated and is kept for backward compatibility. It will removed in the context of CY-1272
+ apiToken.map(t => "api_token" -> t) ++
+ projectToken.map(t => "project_token" -> t)
+
+ private val remoteUrl = new URL(new URL(apiUrl.getOrElse("https://api.codacy.com")), "/2.0").toString()
+
+ /*
+ * Does an API post
+ */
+ def post[T](
+ request: Request[T],
+ value: String,
+ timeoutOpt: Option[RequestTimeout] = None,
+ sleepTime: Option[Int],
+ numRetries: Option[Int]
+ )(implicit reads: Reads[T]): RequestResponse[T] = {
+ val url = s"$remoteUrl/${request.endpoint}"
+ try {
+ val headers = tokens ++ Map("Content-Type" -> "application/json")
+
+ val httpRequest = timeoutOpt match {
+ case Some(timeout) =>
+ Http(url).timeout(connTimeoutMs = timeout.connTimeoutMs, readTimeoutMs = timeout.readTimeoutMs)
+ case None => Http(url)
+ }
+
+ val body = httpRequest
+ .params(request.queryParameters)
+ .headers(headers)
+ .postData(value)
+ .asString
+ .body
+
+ parseJsonAs[T](body) match {
+ case failure: FailedResponse =>
+ retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), failure.message)
+ case success => success
+ }
+ } catch {
+ case NonFatal(ex) => retryPost(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1), ex.getMessage)
+ }
+ }
+
+ private def retryPost[T](
+ request: Request[T],
+ value: String,
+ timeoutOpt: Option[RequestTimeout],
+ sleepTime: Option[Int],
+ numRetries: Option[Int],
+ failureMessage: String
+ )(implicit reads: Reads[T]): RequestResponse[T] = {
+ if (numRetries.exists(x => x > 0)) {
+ sleepTime.map(x => Thread.sleep(x))
+ post(request, value, timeoutOpt, sleepTime, numRetries.map(x => x - 1))
+ } else {
+ RequestResponse.failure(
+ s"Error doing a post to $remoteUrl/${request.endpoint}: exhausted retries due to $failureMessage"
+ )
+ }
+ }
+
+ private def parseJsonAs[T](input: String)(implicit reads: Reads[T]): RequestResponse[T] = {
+ parseJson(input) match {
+ case failure: FailedResponse => failure
+ case SuccessfulResponse(json) =>
+ json
+ .validate[T]
+ .fold(
+ errors => FailedResponse(JsonOps.handleConversionFailure(errors)),
+ converted => SuccessfulResponse(converted)
+ )
+ }
+ }
+
+ private def parseJson(input: String): RequestResponse[JsValue] = {
+ Try(Json.parse(input)) match {
+ case Success(json) =>
+ json
+ .validate[ErrorJson]
+ .fold(_ => SuccessfulResponse(json), apiError => FailedResponse(s"API Error: ${apiError.error}"))
+ case Failure(exception) =>
+ FailedResponse(s"Failed to parse API response as JSON: $input\nUnderlying exception - ${exception.getMessage}")
+ }
+ }
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/client/Request.scala b/api-scala/src/main/scala/com/codacy/api/client/Request.scala
new file mode 100644
index 00000000..3555284e
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/client/Request.scala
@@ -0,0 +1,3 @@
+package com.codacy.api.client
+
+case class Request[T](endpoint: String, classType: Class[T], queryParameters: Map[String, String] = Map.empty)
diff --git a/api-scala/src/main/scala/com/codacy/api/client/RequestResponse.scala b/api-scala/src/main/scala/com/codacy/api/client/RequestResponse.scala
new file mode 100644
index 00000000..4c82e348
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/client/RequestResponse.scala
@@ -0,0 +1,27 @@
+package com.codacy.api.client
+
+sealed trait RequestResponse[+A]
+
+case class SuccessfulResponse[A](value: A) extends RequestResponse[A]
+
+case class FailedResponse(message: String) extends RequestResponse[Nothing]
+
+object RequestResponse {
+
+ def success[A](a: A): RequestResponse[A] = SuccessfulResponse(a)
+
+ def failure[A](message: String): RequestResponse[A] = FailedResponse(message: String)
+
+ def apply[A](r1: RequestResponse[Seq[A]], r2: RequestResponse[Seq[A]]): RequestResponse[Seq[A]] = {
+ r1 match {
+ case SuccessfulResponse(v1) =>
+ r2 match {
+ case SuccessfulResponse(v2) =>
+ SuccessfulResponse(v1 ++ v2)
+ case f @ FailedResponse(_) => f
+ }
+ case f @ FailedResponse(_) => f
+ }
+ }
+
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/client/RequestSuccess.scala b/api-scala/src/main/scala/com/codacy/api/client/RequestSuccess.scala
new file mode 100644
index 00000000..fa9b1180
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/client/RequestSuccess.scala
@@ -0,0 +1,9 @@
+package com.codacy.api.client
+
+import play.api.libs.json.{Json, Reads}
+
+case class RequestSuccess(success: String)
+
+object RequestSuccess {
+ implicit val requestSuccessReads: Reads[RequestSuccess] = Json.reads[RequestSuccess]
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/client/RequestTimeout.scala b/api-scala/src/main/scala/com/codacy/api/client/RequestTimeout.scala
new file mode 100644
index 00000000..546aaf2c
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/client/RequestTimeout.scala
@@ -0,0 +1,6 @@
+package com.codacy.api.client
+
+/**
+ * The socket connection and read timeouts in milliseconds.
+ */
+case class RequestTimeout(connTimeoutMs: Int, readTimeoutMs: Int)
diff --git a/api-scala/src/main/scala/com/codacy/api/helpers/FileHelper.scala b/api-scala/src/main/scala/com/codacy/api/helpers/FileHelper.scala
new file mode 100644
index 00000000..ecfe3455
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/helpers/FileHelper.scala
@@ -0,0 +1,19 @@
+package com.codacy.api.helpers
+
+import java.io.{File, PrintWriter}
+
+import play.api.libs.json._
+
+import scala.util.Try
+
+object FileHelper {
+
+ def writeJsonToFile[A](file: File, value: A)(implicit writes: Writes[A]): Boolean = {
+ val reportJson = Json.stringify(Json.toJson(value))
+ val printWriter = new PrintWriter(file)
+ val result = Try(printWriter.write(reportJson)).isSuccess
+ printWriter.close()
+ result
+ }
+
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/helpers/vcs/GitClient.scala b/api-scala/src/main/scala/com/codacy/api/helpers/vcs/GitClient.scala
new file mode 100644
index 00000000..e4cd94dd
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/helpers/vcs/GitClient.scala
@@ -0,0 +1,41 @@
+package com.codacy.api.helpers.vcs
+
+import java.io.File
+import java.util.Date
+
+import org.eclipse.jgit.api.Git
+import org.eclipse.jgit.lib.{Repository, RepositoryBuilder}
+
+import scala.collection.JavaConverters._
+import scala.util.Try
+
+case class CommitInfo(uuid: String, authorName: String, authorEmail: String, date: Date)
+
+class GitClient(workDirectory: File) {
+
+ val repositoryTry: Try[Repository] = Try(new RepositoryBuilder().findGitDir(workDirectory).readEnvironment().build())
+
+ val repository: Option[Repository] = repositoryTry.toOption
+
+ def latestCommitUuid(): Option[String] = {
+ repositoryTry
+ .map { rep =>
+ val git = new Git(rep)
+ val headRev = git.log().setMaxCount(1).call().asScala.head
+ headRev.getName
+ }
+ .toOption
+ .filter(_.trim.nonEmpty)
+ }
+
+ def latestCommitInfo: Try[CommitInfo] = {
+ repositoryTry.map { rep =>
+ val git = new Git(rep)
+ val headRev = git.log().setMaxCount(1).call().asScala.head
+ val authorIdent = headRev.getAuthorIdent
+
+ CommitInfo(headRev.getName, authorIdent.getName, authorIdent.getEmailAddress, authorIdent.getWhen)
+ }
+ }
+
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/service/CoverageServices.scala b/api-scala/src/main/scala/com/codacy/api/service/CoverageServices.scala
new file mode 100644
index 00000000..c4675bbb
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/service/CoverageServices.scala
@@ -0,0 +1,143 @@
+package com.codacy.api.service
+
+import com.codacy.api.client.{CodacyClient, Request, RequestResponse, RequestSuccess, RequestTimeout}
+import com.codacy.api.{CoverageReport, OrganizationProvider}
+import play.api.libs.json.Json
+
+class CoverageServices(client: CodacyClient) {
+
+ /**
+ * Send coverage report to Codacy endpoint.
+ * This endpoint requires a project token to authenticate the request and identify the project.
+ * Therefore, the client must be initialized with a valid project token.
+ * @param commitUuid commit unique identifier
+ * @param language programing language
+ * @param coverageReport coverage report being sent to Codacy
+ * @param partial flag that signals if the report operation will be broken in multiple operations
+ * @param timeoutOpt socket connection and read timeouts in milliseconds
+ * @return Request response
+ */
+ def sendReport(
+ commitUuid: String,
+ language: String,
+ coverageReport: CoverageReport,
+ partial: Boolean = false,
+ timeoutOpt: Option[RequestTimeout] = None,
+ sleepTime: Option[Int] = None,
+ numRetries: Option[Int] = None,
+ ): RequestResponse[RequestSuccess] = {
+ val endpoint = s"coverage/$commitUuid/${encodePathSegment(language.toLowerCase)}"
+
+ postRequest(endpoint, coverageReport, partial, timeoutOpt, sleepTime, numRetries)
+ }
+
+ /**
+ * Send final notification signaling the end of the report operation.
+ * This endpoint requires an account token to authenticate the request and identify the project.
+ * Therefore, the client must be initialized with a valid account token.
+ * @param commitUuid commit unique identifier
+ * @param timeoutOpt socket connection and read timeouts in milliseconds
+ * @return Request Response
+ */
+ def sendFinalNotification(
+ commitUuid: String,
+ timeoutOpt: Option[RequestTimeout] = None,
+ sleepTime: Option[Int] = None,
+ numRetries: Option[Int] = None,
+ ): RequestResponse[RequestSuccess] = {
+ val endpoint = s"commit/$commitUuid/coverageFinal"
+
+ postEmptyRequest(endpoint, timeoutOpt, sleepTime, numRetries)
+ }
+
+ /**
+ * Send coverage report with a project name to Codacy endpoint.
+ * This endpoint requires an account token to authenticate the request.
+ * Therefore, the client must be initialized with a valid account token.
+ * @param username reporter's username
+ * @param projectName name of the project the report pertains
+ * @param commitUuid commit unique identifier
+ * @param language programing language
+ * @param coverageReport coverage report being reported
+ * @param partial flag that signals if the report operation will be broken in multiple operations
+ * @param timeoutOpt socket connection and read timeouts in milliseconds
+ * @return Request Response
+ */
+ def sendReportWithProjectName(
+ provider: OrganizationProvider.Value,
+ username: String,
+ projectName: String,
+ commitUuid: String,
+ language: String,
+ coverageReport: CoverageReport,
+ partial: Boolean = false,
+ timeoutOpt: Option[RequestTimeout] = None,
+ sleepTime: Option[Int] = None,
+ numRetries: Option[Int] = None,
+ ): RequestResponse[RequestSuccess] = {
+ val endpoint =
+ s"${provider.toString}/$username/$projectName/commit/$commitUuid/coverage/${encodePathSegment(language.toLowerCase)}"
+ postRequest(endpoint, coverageReport, partial, timeoutOpt, sleepTime, numRetries)
+ }
+
+ /**
+ * Send final notification with a project name, signaling the end of the report operation.
+ * This endpoint requires an account token to authenticate the request.
+ * Therefore, the client must be initialized with a valid account token.
+ * @param username reporter's username
+ * @param projectName name of the project the report pertains
+ * @param commitUuid commit unique identifier
+ * @param timeoutOpt socket connection and read timeouts in milliseconds
+ * @return Request Response
+ */
+ def sendFinalWithProjectName(
+ provider: OrganizationProvider.Value,
+ username: String,
+ projectName: String,
+ commitUuid: String,
+ timeoutOpt: Option[RequestTimeout] = None,
+ sleepTime: Option[Int] = None,
+ numRetries: Option[Int] = None
+ ): RequestResponse[RequestSuccess] = {
+ val endpoint = s"${provider.toString}/$username/$projectName/commit/$commitUuid/coverageFinal"
+
+ postEmptyRequest(endpoint, timeoutOpt, sleepTime, numRetries)
+ }
+
+ private def postRequest(
+ endpoint: String,
+ coverageReport: CoverageReport,
+ partial: Boolean,
+ timeoutOpt: Option[RequestTimeout],
+ sleepTime: Option[Int],
+ numRetries: Option[Int]
+ ) = {
+ val queryParams = getQueryParameters(partial)
+
+ val jsonString = serializeCoverageReport(coverageReport)
+
+ client.post(Request(endpoint, classOf[RequestSuccess], queryParams), jsonString, timeoutOpt, sleepTime, numRetries)
+ }
+
+ private def postEmptyRequest(
+ endpoint: String,
+ timeoutOpt: Option[RequestTimeout],
+ sleepTime: Option[Int],
+ numRetries: Option[Int]
+ ) =
+ client.post(Request(endpoint, classOf[RequestSuccess]), "{}", timeoutOpt, sleepTime, numRetries)
+
+ private def getQueryParameters(partial: Boolean) = {
+ Map("partial" -> partial.toString)
+ }
+ private def serializeCoverageReport(coverageReport: CoverageReport) =
+ Json.stringify(Json.toJson(coverageReport))
+
+ /**
+ * Any encoding that we do here, needs to have the same output
+ * of play.utils.UriEncoding.encodePathSegment for our languages.
+ * https://github.com/playframework/playframework/blob/316fbd61c9fc6a6081a3aeef7e773c8bbccd0b6b/core/play/src/main/scala/play/utils/UriEncoding.scala#L50
+ */
+ private def encodePathSegment(segment: String): String = segment.replaceAll(" ", "%20")
+
+}
diff --git a/api-scala/src/main/scala/com/codacy/api/util/JsonOps.scala b/api-scala/src/main/scala/com/codacy/api/util/JsonOps.scala
new file mode 100644
index 00000000..89be5fb6
--- /dev/null
+++ b/api-scala/src/main/scala/com/codacy/api/util/JsonOps.scala
@@ -0,0 +1,11 @@
+package com.codacy.api.util
+
+import play.api.libs.json.{JsError, JsPath, Json, JsonValidationError}
+
+object JsonOps {
+
+ def handleConversionFailure(error: Seq[(JsPath, Seq[JsonValidationError])]): String = {
+ val jsonError = Json.stringify(JsError.toJson(error.toList))
+ s"Json conversion error: $jsonError"
+ }
+}
diff --git a/api-scala/src/test/scala/com/codacy/api/GitClientTest.scala b/api-scala/src/test/scala/com/codacy/api/GitClientTest.scala
new file mode 100644
index 00000000..7001d8f2
--- /dev/null
+++ b/api-scala/src/test/scala/com/codacy/api/GitClientTest.scala
@@ -0,0 +1,21 @@
+package com.codacy.api
+
+import com.codacy.api.helpers.vcs.GitClient
+import java.nio.file.Paths
+import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.OptionValues._
+
+class GitClientTest extends FlatSpec with Matchers {
+
+ "GitClient" should "latestCommitUuid" in {
+
+ val file = Paths.get("").toAbsolutePath.toFile
+
+ val latest: Option[String] = new GitClient(file).latestCommitUuid()
+
+ latest shouldNot be(None)
+
+ latest.value shouldNot be('empty)
+ }
+
+}
diff --git a/build.sbt b/build.sbt
index c38c63f6..3fb8c488 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,6 +1,6 @@
inThisBuild(
Seq(
- scalaVersion := "2.12.11",
+ scalaVersion := "2.12.18",
scalacOptions := Seq(
"-deprecation",
"-feature",
@@ -28,9 +28,6 @@ libraryDependencies ++= Seq(
"org.mockito" %% "mockito-scala-scalatest" % "1.7.1" % Test
)
-configs(IntegrationTest)
-Defaults.itSettings
-
assembly / mainClass := Some("com.codacy.CodacyCoverageReporter")
assembly / assemblyMergeStrategy := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
@@ -39,6 +36,7 @@ assembly / assemblyMergeStrategy := {
}
assembly / test := {}
crossPaths := false
+run / fork := true
// HACK: Since we are only using the public resolvers we need to remove the private for it to not fail
resolvers ~= {
@@ -83,16 +81,27 @@ nativeImageOptions := Seq(
dependsOn(coverageParser)
+lazy val apiScala = project
+ .in(file("api-scala"))
+ .settings(
+ libraryDependencies ++= Seq(
+ "com.typesafe.play" %% "play-json" % "2.8.2",
+ "org.scalaj" %% "scalaj-http" % "2.4.2",
+ "org.eclipse.jgit" % "org.eclipse.jgit" % "4.8.0.201706111038-r",
+ "org.scalatest" %% "scalatest" % "3.0.8" % Test
+ )
+ )
+
lazy val coverageParser = project
.in(file("coverage-parser"))
.settings(
libraryDependencies ++= Seq(
- "com.codacy" %% "codacy-api-scala" % "7.0.7",
"com.codacy" %% "codacy-plugins-api" % "5.2.0",
"org.scala-lang.modules" %% "scala-xml" % "1.2.0",
"org.scalatest" %% "scalatest" % "3.0.8" % Test
)
)
+ .dependsOn(apiScala)
// https://github.com/sbt/sbt-assembly/issues/146
ThisBuild / assemblyMergeStrategy := {
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CloverParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CloverParser.scala
index 2a60e120..fe43737d 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CloverParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CloverParser.scala
@@ -4,7 +4,7 @@ import java.io.File
import java.nio.file.Paths
import com.codacy.api.{CoverageFileReport, CoverageReport}
-import com.codacy.parsers.util.{MathUtils, TextUtils}
+import com.codacy.parsers.util.TextUtils
import com.codacy.parsers.{CoverageParser, XmlReportParser}
import scala.xml.{Elem, Node, NodeSeq}
@@ -27,10 +27,6 @@ object CloverParser extends CoverageParser with XmlReportParser {
override def getRootNode(xml: Elem): NodeSeq = xml \\ CoverageTag
private def parseReportNode(rootProject: File, report: NodeSeq): Either[String, CoverageReport] = {
- val metricsNode = report \ ProjectTag \ MetricsTag
- val totalCoverage = getCoveragePercentage(metricsNode).left
- .map(errorMessage => s"Could not retrieve total coverage from metrics tag in project: $errorMessage")
-
val rootPath = TextUtils.sanitiseFilename(rootProject.getAbsolutePath)
val coverageFiles = (report \\ "file").foldLeft[Either[String, Seq[CoverageFileReport]]](Right(List())) {
@@ -42,16 +38,8 @@ object CloverParser extends CoverageParser with XmlReportParser {
}
for {
- totalCoverage <- totalCoverage
coverageFiles <- coverageFiles
- } yield CoverageReport(totalCoverage, coverageFiles)
- }
-
- private def getCoveragePercentage(metrics: NodeSeq): Either[String, Int] = {
- for {
- totalStatements <- getFirstNonEmptyValueAsInt(metrics, "statements")
- coveredStatements <- getFirstNonEmptyValueAsInt(metrics, "coveredstatements")
- } yield MathUtils.computePercentage(coveredStatements, totalStatements)
+ } yield CoverageReport(coverageFiles)
}
private def getCoverageFileReport(rootPath: String, fileNode: Node): Either[String, CoverageFileReport] = {
@@ -72,15 +60,9 @@ object CloverParser extends CoverageParser with XmlReportParser {
for {
relativeFilePath <- relativeFilePath
- metricsNode = fileNode \ MetricsTag
- fileCoverage <- getCoveragePercentage(metricsNode).left
- .map(
- errorMessage =>
- s"Could not retrieve file coverage from metrics tag for file '$relativeFilePath': $errorMessage"
- )
linesCoverage <- getLinesCoverage(fileNode).left
.map(errorMessage => s"Could not retrieve lines coverage for file '$relativeFilePath': $errorMessage")
- } yield CoverageFileReport(relativeFilePath, fileCoverage, linesCoverage)
+ } yield CoverageFileReport(relativeFilePath, linesCoverage)
}
private def getLinesCoverage(fileNode: Node): Either[String, Map[Int, Int]] = {
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala
index b54790ab..878bc63e 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/CoberturaParser.scala
@@ -32,8 +32,6 @@ object CoberturaParser extends CoverageParser with XmlReportParser {
private def parseReportNode(projectRoot: File, report: NodeSeq) = {
val projectRootStr: String = TextUtils.sanitiseFilename(projectRoot.getAbsolutePath)
- val total = math.round(TextUtils.asFloat(report \\ CoverageTag \@ LineRateAttribute) * 100)
-
val fileReports: List[CoverageFileReport] = (for {
(filename, classes) <- (report \\ "class").groupBy(c => c \@ "filename")
} yield {
@@ -41,16 +39,10 @@ object CoberturaParser extends CoverageParser with XmlReportParser {
lineCoverage(cleanFilename, classes)
})(collection.breakOut)
- CoverageReport(total, fileReports)
+ CoverageReport(fileReports)
}
private def lineCoverage(sourceFilename: String, classes: NodeSeq): CoverageFileReport = {
- val classHit = (classes \\ s"@$LineRateAttribute").map { total =>
- val totalValue = TextUtils.asFloat(total.text)
- math.round(totalValue * 100)
- }
- val fileHit = if (classHit.nonEmpty) { classHit.sum / classHit.length } else 0
-
val map = mutable.Map.empty[Int, Int]
for {
@@ -64,6 +56,6 @@ object CoberturaParser extends CoverageParser with XmlReportParser {
map(key) = sum.toIntOrMaxValue
}
- CoverageFileReport(sourceFilename, fileHit, map.toMap)
+ CoverageFileReport(sourceFilename, map.toMap)
}
}
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/DotcoverParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/DotcoverParser.scala
index 6dfbfe97..eeec42ca 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/DotcoverParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/DotcoverParser.scala
@@ -3,7 +3,7 @@ package com.codacy.parsers.implementation
import java.io.File
import com.codacy.api.{CoverageFileReport, CoverageReport}
-import com.codacy.parsers.util.{MathUtils, TextUtils}
+import com.codacy.parsers.util.TextUtils
import com.codacy.parsers.{CoverageParser, XmlReportParser}
import scala.xml.{Elem, NodeSeq}
@@ -29,8 +29,6 @@ object DotcoverParser extends CoverageParser with XmlReportParser {
private def parseReportNode(rootProject: File, rootNode: NodeSeq): CoverageReport = {
val projectRootStr: String = TextUtils.sanitiseFilename(rootProject.getAbsolutePath)
- val totalCoverage = (rootNode \@ CoverageAttribute).toInt
-
val fileIndices: Map[Int, String] = (rootNode \ "FileIndices" \ "File").map { x =>
(x \@ "Index").toInt -> (x \@ "Name")
}.toMap
@@ -43,10 +41,9 @@ object DotcoverParser extends CoverageParser with XmlReportParser {
lineCoverage = getLineCoverage(statements)
totalLines = lineCoverage.keys.size
coveredLines = lineCoverage.values.count(_ > 0)
- total = MathUtils.computePercentage(coveredLines, totalLines)
- } yield CoverageFileReport(filename, total, lineCoverage)
+ } yield CoverageFileReport(filename, lineCoverage)
- CoverageReport(totalCoverage, fileReports.toSeq)
+ CoverageReport(fileReports.toSeq)
}
private def getLineCoverage(statementNodes: NodeSeq) = {
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/GoParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/GoParser.scala
index c539c481..03234d64 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/GoParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/GoParser.scala
@@ -56,12 +56,12 @@ object GoParser extends CoverageParser {
}
}
- accum :+ CoverageFileReport(filename, 0, coverage)
+ accum :+ CoverageFileReport(filename, coverage)
}
})
- CoverageReport(0, coverageFileReports)
+ CoverageReport(coverageFileReports)
}
private def parseAllCoverageInfo(lines: List[String]): List[GoCoverageInfo] = {
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/JacocoParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/JacocoParser.scala
index cb3f69da..80ffee39 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/JacocoParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/JacocoParser.scala
@@ -41,7 +41,7 @@ object JacocoParser extends CoverageParser with XmlReportParser {
lineCoverage(filename, sourceFile)
}
- CoverageReport(total, filesCoverage)
+ CoverageReport(filesCoverage)
}
}
@@ -59,15 +59,6 @@ object JacocoParser extends CoverageParser with XmlReportParser {
}
private def lineCoverage(filename: String, fileNode: Node): CoverageFileReport = {
- val lineHit = (fileNode \ "counter").collect {
- case counter if (counter \@ "type") == "LINE" =>
- val covered = TextUtils.asFloat((counter \@ "covered"))
- val missed = TextUtils.asFloat((counter \@ "missed"))
- (if ((covered + missed) > 0) (covered / (covered + missed)) * 100 else 0f).toInt
- }
-
- val fileHit = if (lineHit.sum != 0) { lineHit.sum / lineHit.length } else 0
-
val lineHitMap: Map[Int, Int] = (fileNode \\ "line")
.map { line =>
(line \@ "nr").toInt -> LineCoverage((line \@ "mi").toInt, (line \@ "ci").toInt)
@@ -77,6 +68,6 @@ object JacocoParser extends CoverageParser with XmlReportParser {
key -> (if (lineCoverage.coveredInstructions > 0) 1 else 0)
}(collection.breakOut)
- CoverageFileReport(filename, fileHit, lineHitMap)
+ CoverageFileReport(filename, lineHitMap)
}
}
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/LCOVParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/LCOVParser.scala
index f486cfdb..3c935485 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/LCOVParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/LCOVParser.scala
@@ -5,7 +5,7 @@ import com.codacy.parsers.util.MathUtils._
import com.codacy.api.{CoverageFileReport, CoverageReport}
import java.io.File
-import com.codacy.parsers.util.{MathUtils, XMLoader}
+import com.codacy.parsers.util.XMLoader
import scala.io.Source
import scala.util.{Failure, Success, Try}
@@ -36,7 +36,7 @@ object LCOVParser extends CoverageParser {
(accum, next) =>
accum.flatMap {
case reports if next startsWith SF =>
- Right(CoverageFileReport(next stripPrefix SF, 0, Map()) +: reports)
+ Right(CoverageFileReport(next.stripPrefix(SF), Map()) +: reports)
case reports if next startsWith DA =>
reports.headOption match {
case Some(value) =>
@@ -56,12 +56,7 @@ object LCOVParser extends CoverageParser {
)
coverageFileReports.map { fileReports =>
val totalFileReport = fileReports.map { report =>
- val coveredLines = report.coverage.count { case (_, hit) => hit > 0 }
- val totalLines = report.coverage.size
- val fileCoverage =
- MathUtils.computePercentage(coveredLines, totalLines)
-
- CoverageFileReport(report.filename, fileCoverage, report.coverage)
+ CoverageFileReport(report.filename, report.coverage)
}
val (covered, total) = totalFileReport
@@ -73,8 +68,7 @@ object LCOVParser extends CoverageParser {
(accumCovered + nextCovered, accumTotal + nextTotal)
}
- val totalCoverage = MathUtils.computePercentage(covered, total)
- CoverageReport(totalCoverage, totalFileReport)
+ CoverageReport(totalFileReport)
}
}
}
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/OpenCoverParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/OpenCoverParser.scala
index 5de6c921..455b9e98 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/OpenCoverParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/OpenCoverParser.scala
@@ -3,7 +3,7 @@ package com.codacy.parsers.implementation
import java.io.File
import com.codacy.api.{CoverageFileReport, CoverageReport}
-import com.codacy.parsers.util.{MathUtils, TextUtils}
+import com.codacy.parsers.util.TextUtils
import com.codacy.parsers.{CoverageParser, XmlReportParser}
import scala.xml.{Elem, NodeSeq}
@@ -46,12 +46,9 @@ object OpenCoverParser extends CoverageParser with XmlReportParser {
lineCoverage = getLineCoverage(methods, sanitisedFileName)
totalLines = lineCoverage.size
coveredLines = lineCoverage.count { case (_, visitCount) => visitCount > 0 }
- coverage = MathUtils.computePercentage(coveredLines, totalLines)
- } yield CoverageFileReport(sanitisedFileName, coverage, lineCoverage)).toSeq
+ } yield CoverageFileReport(sanitisedFileName, lineCoverage)).toSeq
- val totalCoverage = computeTotalCoverage(fileReports)
-
- CoverageReport(totalCoverage, fileReports)
+ CoverageReport(fileReports)
}
private def getLineCoverage(methodNodes: NodeSeq, filename: String) = {
@@ -62,16 +59,4 @@ object OpenCoverParser extends CoverageParser with XmlReportParser {
lineCoverage.toMap
}
-
- private def computeTotalCoverage(fileReports: Seq[CoverageFileReport]) = {
- val (totalLines, coveredLines) = fileReports
- .foldLeft((0, 0)) {
- case ((total, covered), f) =>
- val totalLines = f.coverage.size
- val coveredLines = (f.total * totalLines) / 100
- (total + totalLines, covered + coveredLines)
- }
-
- MathUtils.computePercentage(coveredLines, totalLines)
- }
}
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/PhpUnitXmlParser.scala b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/PhpUnitXmlParser.scala
index 62688b4f..6b0814cd 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/implementation/PhpUnitXmlParser.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/implementation/PhpUnitXmlParser.scala
@@ -14,7 +14,6 @@ object PhpUnitXmlParser extends CoverageParser with XmlReportParser {
private val PhpUnitTag = "phpunit"
private val ProjectTag = "project"
private val DirectoryTag = "directory"
- private val TotalsTag = "totals"
private val XmlParseErrorMessage = s"Could not find top level <$PhpUnitTag> tag";
override def parse(rootProject: File, reportFile: File): Either[String, CoverageReport] =
@@ -35,9 +34,7 @@ object PhpUnitXmlParser extends CoverageParser with XmlReportParser {
val projectRootPath = TextUtils.sanitiseFilename(projectRoot.getAbsolutePath)
val codeDirectory = report \ ProjectTag \ DirectoryTag \@ "name"
val fileReports = makeFileReports(fileNodes, projectRootPath, codeDirectory, reportRootPath)
-
- val totalPercentage = getTotalsCoveragePercentage(report \ ProjectTag \ DirectoryTag \ TotalsTag)
- fileReports.map(CoverageReport(totalPercentage, _))
+ fileReports.map(CoverageReport(_))
}
private def makeFileReports(
@@ -50,10 +47,9 @@ object PhpUnitXmlParser extends CoverageParser with XmlReportParser {
for (f <- fileNodes) {
val reportFileName = f \@ "href"
val fileName = getSourceFileName(projectRootPath, codeDirectory, reportFileName)
- val coveragePercentage = getTotalsCoveragePercentage(f \ TotalsTag)
getLineCoverage(reportRootPath, reportFileName) match {
case Right(lineCoverage) =>
- builder += CoverageFileReport(fileName, coveragePercentage, lineCoverage)
+ builder += CoverageFileReport(fileName, lineCoverage)
case Left(message) => return Left(message)
}
}
@@ -72,11 +68,6 @@ object PhpUnitXmlParser extends CoverageParser with XmlReportParser {
lineCoverage
}
- private def getTotalsCoveragePercentage(totals: NodeSeq) = {
- val percentageStr = (totals \ "lines" \@ "percent").dropRight(1)
- scala.math.round(percentageStr.toFloat)
- }
-
private def getSourceFileName(pathToRemove: String, codeRootDirectory: String, reportRelativePath: String) = {
new File(codeRootDirectory, reportRelativePath).getAbsolutePath
.stripPrefix(pathToRemove)
diff --git a/coverage-parser/src/main/scala/com/codacy/parsers/util/MathUtils.scala b/coverage-parser/src/main/scala/com/codacy/parsers/util/MathUtils.scala
index a3914c93..8e332ad3 100644
--- a/coverage-parser/src/main/scala/com/codacy/parsers/util/MathUtils.scala
+++ b/coverage-parser/src/main/scala/com/codacy/parsers/util/MathUtils.scala
@@ -2,10 +2,6 @@ package com.codacy.parsers.util
object MathUtils {
- def computePercentage(part: Int, total: Int): Int = {
- if (total == 0) 0 else math.round((part.toFloat / total) * 100)
- }
-
implicit class ParseIntOps(val s: String) extends AnyVal {
def toIntOrMaxValue: Int = BigInt(s).toIntOrMaxValue
}
diff --git a/coverage-parser/src/test/resources/test_invalid_clover.xml b/coverage-parser/src/test/resources/test_invalid_clover.xml
deleted file mode 100644
index bbd94707..00000000
--- a/coverage-parser/src/test/resources/test_invalid_clover.xml
+++ /dev/null
@@ -1,365 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/CloverParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/CloverParserTest.scala
index 8376b98c..676bb41c 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/CloverParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/CloverParserTest.scala
@@ -19,9 +19,9 @@ class CloverParserTest extends WordSpec with Matchers with EitherValues {
val parseResult = CloverParser.parse(new File("."), new File(nonExistentReportPath))
// Assert
- parseResult shouldBe Left(
- "Unparseable report. coverage-parser/src/test/resources/non-existent.xml (No such file or directory)"
- )
+ val error = parseResult.left.value
+ error should startWith("Unparseable report. ")
+ error should endWith("coverage-parser/src/test/resources/non-existent.xml (No such file or directory)")
}
"the report is not in the Clover format" in {
@@ -34,20 +34,6 @@ class CloverParserTest extends WordSpec with Matchers with EitherValues {
// Assert
parseResult shouldBe Left("Invalid report. Could not find tag hierarchy tags.")
}
-
- "the report is missing the statements attribute in the file metrics tag" in {
- // Arrange
- val invalidCloverReportPath = "coverage-parser/src/test/resources/test_invalid_clover.xml"
-
- // Act
- val parseResult = CloverParser.parse(new File("."), new File(invalidCloverReportPath))
-
- // Assert
- parseResult shouldBe Left(
- "Could not retrieve file coverage from metrics tag for file 'home/codacy-php/src/Codacy/Coverage/Parser/Parser.php': Could not find attribute with name 'statements'"
- )
- }
-
}
val cloverReportPath = "coverage-parser/src/test/resources/test_clover.xml"
@@ -118,18 +104,6 @@ class CloverParserTest extends WordSpec with Matchers with EitherValues {
fileReports should have length expectedNumberOfFiles
}
- "return a report with the expected total coverage" in {
- // Arrange
- val expectedTotalCoverage = 38
-
- // Act
- val coverageTotal =
- CloverParser.parse(new File("/home/codacy-php/"), new File(cloverReportPath)).right.value.total
-
- // Assert
- coverageTotal shouldBe expectedTotalCoverage
- }
-
"return a report with the expected relative file paths" in {
// Arrange
val expectedFilePaths = Seq(
@@ -153,26 +127,6 @@ class CloverParserTest extends WordSpec with Matchers with EitherValues {
parsedReportFilePaths should contain theSameElementsAs expectedFilePaths
}
- "return a report with the expected file coverage" in {
- // Arrange
- val filePath = "src/Codacy/Coverage/Parser/Parser.php"
- val expectedFileCoverage = 33
-
- // Act
- val fileTotalCoverage =
- CloverParser
- .parse(new File("/home/codacy-php/"), new File(cloverReportPath))
- .right
- .value
- .fileReports
- .find(_.filename == filePath)
- .getOrElse(fail(s"Could not find report for file:$filePath"))
- .total
-
- // Assert
- fileTotalCoverage shouldBe expectedFileCoverage
- }
-
"return a report with the expected file line coverage" in {
// Arrange
val filePath = "src/Codacy/Coverage/Report/CoverageReport.php"
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/CoberturaParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/CoberturaParserTest.scala
index 93e7830c..528988e0 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/CoberturaParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/CoberturaParserTest.scala
@@ -26,41 +26,29 @@ class CoberturaParserTest extends WordSpec with BeforeAndAfterAll with Matchers
CoberturaParser.parse(new File("."), new File("coverage-parser/src/test/resources/test_cobertura.xml"))
val testReport = CoverageReport(
- 87,
List(
- CoverageFileReport(
- "coverage-parser/src/test/resources/TestSourceFile2.scala",
- 87,
- Map(1 -> 1, 2 -> 1, 3 -> 1)
- ),
CoverageFileReport(
"coverage-parser/src/test/resources/TestSourceFile.scala",
- 87,
Map(5 -> 1, 10 -> 1, 6 -> 2, 9 -> Int.MaxValue, 3 -> 0, 4 -> 1, 7 -> 1, 8 -> 3)
- )
+ ),
+ CoverageFileReport("coverage-parser/src/test/resources/TestSourceFile2.scala", Map(1 -> 1, 2 -> 1, 3 -> 1)),
)
)
reader.right.value should equal(testReport)
}
- "no crash on thousands separators" in {
+ "not crash on thousands separators" in {
val reader =
CoberturaParser.parse(new File("."), new File("coverage-parser/src/test/resources/thousand_sep_cobertura.xml"))
val testReport = CoverageReport(
- 87,
List(
- CoverageFileReport(
- "coverage-parser/src/test/resources/TestSourceFile2.scala",
- 87,
- Map(1 -> 1, 2 -> 1, 3 -> 1)
- ),
CoverageFileReport(
"coverage-parser/src/test/resources/TestSourceFile.scala",
- 87,
Map(5 -> 1, 10 -> 1, 6 -> 2, 9 -> 1, 9 -> 0, 8 -> 1, 4 -> 1)
- )
+ ),
+ CoverageFileReport("coverage-parser/src/test/resources/TestSourceFile2.scala", Map(1 -> 1, 2 -> 1, 3 -> 1)),
)
)
@@ -72,18 +60,12 @@ class CoberturaParserTest extends WordSpec with BeforeAndAfterAll with Matchers
CoberturaParser.parse(new File("."), new File("coverage-parser/src/test/resources/windows_paths_cobertura.xml"))
val testReport = CoverageReport(
- 87,
List(
- CoverageFileReport(
- "coverage-parser/src/test/resources/TestSourceFile2.scala",
- 87,
- Map(1 -> 1, 2 -> 1, 3 -> 1)
- ),
CoverageFileReport(
"coverage-parser/src/test/resources/TestSourceFile.scala",
- 87,
Map(5 -> 1, 10 -> 1, 6 -> 2, 9 -> 1, 3 -> 0, 4 -> 1)
- )
+ ),
+ CoverageFileReport("coverage-parser/src/test/resources/TestSourceFile2.scala", Map(1 -> 1, 2 -> 1, 3 -> 1)),
)
)
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/CoverageParserFactoryTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/CoverageParserFactoryTest.scala
index 6446a3b0..ff9ff629 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/CoverageParserFactoryTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/CoverageParserFactoryTest.scala
@@ -11,18 +11,12 @@ class CoverageParserFactoryTest extends WordSpec with BeforeAndAfterAll with Mat
"get report with unspecified parser" in {
val expectedReport = CoverageReport(
- 87,
List(
- CoverageFileReport(
- "coverage-parser/src/test/resources/TestSourceFile2.scala",
- 87,
- Map(1 -> 1, 2 -> 1, 3 -> 1)
- ),
CoverageFileReport(
"coverage-parser/src/test/resources/TestSourceFile.scala",
- 87,
Map(5 -> 1, 10 -> 1, 6 -> 2, 9 -> 1, 3 -> 0, 4 -> 1, 7 -> 1, 8 -> 3, 9 -> Int.MaxValue)
- )
+ ),
+ CoverageFileReport("coverage-parser/src/test/resources/TestSourceFile2.scala", Map(1 -> 1, 2 -> 1, 3 -> 1))
)
)
@@ -34,18 +28,12 @@ class CoverageParserFactoryTest extends WordSpec with BeforeAndAfterAll with Mat
"get report with jacoco parser" in {
val expectedReport = CoverageReport(
- 73,
List(
CoverageFileReport(
"org/eluder/coverage/sample/InnerClassCoverage.java",
- 81,
Map(10 -> 1, 6 -> 1, 9 -> 1, 13 -> 1, 22 -> 1, 27 -> 0, 12 -> 1, 3 -> 1, 16 -> 1, 26 -> 0, 19 -> 1)
),
- CoverageFileReport(
- "org/eluder/coverage/sample/SimpleCoverage.java",
- 50,
- Map(3 -> 1, 6 -> 1, 10 -> 0, 11 -> 0)
- )
+ CoverageFileReport("org/eluder/coverage/sample/SimpleCoverage.java", Map(3 -> 1, 6 -> 1, 10 -> 0, 11 -> 0))
)
)
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/DotCoverParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/DotCoverParserTest.scala
index ce5808f8..37ca2d63 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/DotCoverParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/DotCoverParserTest.scala
@@ -42,25 +42,17 @@ class DotCoverParserTest extends WordSpec with BeforeAndAfterAll with Matchers w
).sorted
}
- "return the expected total coverage" in {
- val reader = DotcoverParser.parse(new File("."), new File(dotCoverReport))
- reader.right.value.total shouldBe 72
- }
-
"return the expected coverage report" in {
val reader = DotcoverParser.parse(new File("."), new File(dotCoverReport))
reader.right.value shouldBe CoverageReport(
- 72,
List(
CoverageFileReport(
"src/Coverage/FooBar.cs",
- 57,
Map(10 -> 1, 21 -> 1, 9 -> 1, 13 -> 0, 17 -> 1, 19 -> 0, 15 -> 0)
),
CoverageFileReport(
"src/Tests/FooBarTests.cs",
- 100,
Map(
14 -> 1,
20 -> 1,
@@ -76,13 +68,9 @@ class DotCoverParserTest extends WordSpec with BeforeAndAfterAll with Matchers w
15 -> 1
)
),
- CoverageFileReport("src/Coverage/Program.cs", 0, Map(8 -> 0, 9 -> 0, 10 -> 0)),
- CoverageFileReport(
- "src/Coverage/Bar.cs",
- 57,
- Map(10 -> 0, 14 -> 1, 9 -> 1, 12 -> 0, 11 -> 0, 8 -> 1, 15 -> 1)
- ),
- CoverageFileReport("src/Coverage/Foo.cs", 100, Map(8 -> 1, 9 -> 1, 10 -> 1))
+ CoverageFileReport("src/Coverage/Program.cs", Map(8 -> 0, 9 -> 0, 10 -> 0)),
+ CoverageFileReport("src/Coverage/Bar.cs", Map(10 -> 0, 14 -> 1, 9 -> 1, 12 -> 0, 11 -> 0, 8 -> 1, 15 -> 1)),
+ CoverageFileReport("src/Coverage/Foo.cs", Map(8 -> 1, 9 -> 1, 10 -> 1))
)
)
}
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/GoParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/GoParserTest.scala
index a50f5a74..5f6a299a 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/GoParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/GoParserTest.scala
@@ -29,11 +29,9 @@ class GoParserTest extends WordSpec with Matchers with EitherValues {
val reader = GoParser.parse(new File("."), new File("coverage-parser/src/test/resources/test_go.out"))
val testReport = CoverageReport(
- 0,
List(
CoverageFileReport(
"example.com/m/v2/hello.go",
- 0,
Map(5 -> 0, 14 -> 1, 6 -> 0, 13 -> 1, 17 -> 1, 12 -> 1, 7 -> 0, 18 -> 1, 11 -> 1, 19 -> 1)
)
)
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/JacocoParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/JacocoParserTest.scala
index 6fd54920..9e3c7281 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/JacocoParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/JacocoParserTest.scala
@@ -24,18 +24,12 @@ class JacocoParserTest extends WordSpec with BeforeAndAfterAll with Matchers wit
val reader = JacocoParser.parse(new File("."), new File("coverage-parser/src/test/resources/test_jacoco.xml"))
val testReport = CoverageReport(
- 73,
List(
CoverageFileReport(
"org/eluder/coverage/sample/InnerClassCoverage.java",
- 81,
Map(10 -> 1, 6 -> 1, 9 -> 1, 13 -> 1, 22 -> 1, 27 -> 0, 12 -> 1, 3 -> 1, 16 -> 1, 26 -> 0, 19 -> 1)
),
- CoverageFileReport(
- "org/eluder/coverage/sample/SimpleCoverage.java",
- 50,
- Map(3 -> 1, 6 -> 1, 10 -> 0, 11 -> 0)
- )
+ CoverageFileReport("org/eluder/coverage/sample/SimpleCoverage.java", Map(3 -> 1, 6 -> 1, 10 -> 0, 11 -> 0))
)
)
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/LCOVParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/LCOVParserTest.scala
index 65582f51..9fae5854 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/LCOVParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/LCOVParserTest.scala
@@ -34,16 +34,10 @@ class LCOVParserTest extends WordSpec with BeforeAndAfterAll with Matchers with
val reader = LCOVParser.parse(new File("."), new File("coverage-parser/src/test/resources/test_lcov.lcov"))
val testReport = CoverageReport(
- 86,
List(
- CoverageFileReport(
- "coverage-parser/src/test/resources/TestSourceFile2.scala",
- 100,
- Map(1 -> 1, 2 -> 1, 3 -> 1)
- ),
+ CoverageFileReport("coverage-parser/src/test/resources/TestSourceFile2.scala", Map(1 -> 1, 2 -> 1, 3 -> 1)),
CoverageFileReport(
"coverage-parser/src/test/resources/TestSourceFile.scala",
- 75,
Map(3 -> 0, 4 -> 1, 5 -> 1, 6 -> 2)
)
)
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/OpenCoverParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/OpenCoverParserTest.scala
index 26ee962b..2647c5d8 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/OpenCoverParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/OpenCoverParserTest.scala
@@ -34,21 +34,14 @@ class OpenCoverParserTest extends WordSpec with BeforeAndAfterAll with Matchers
reader.right.value.fileReports.map(_.filename).sorted shouldBe Seq("bar.cs", "foo.cs", "foobar.cs").sorted
}
- "return the expected total coverage" in {
- val reader = OpenCoverParser.parse(new File("."), new File(openCoverReportPath))
-
- reader.right.value.total shouldBe 50
- }
-
"return the expected report" in {
val reader = OpenCoverParser.parse(new File("."), new File(openCoverReportPath))
reader.right.value shouldBe CoverageReport(
- 50,
List(
- CoverageFileReport("bar.cs", 0, Map(10 -> 0)),
- CoverageFileReport("foo.cs", 100, Map(10 -> 1)),
- CoverageFileReport("foobar.cs", 50, Map(10 -> 0, 20 -> 1))
+ CoverageFileReport("foo.cs", Map(10 -> 1)),
+ CoverageFileReport("bar.cs", Map(10 -> 0)),
+ CoverageFileReport("foobar.cs", Map(10 -> 0, 20 -> 1))
)
)
}
diff --git a/coverage-parser/src/test/scala/com/codacy/parsers/PhpUnitXmlParserTest.scala b/coverage-parser/src/test/scala/com/codacy/parsers/PhpUnitXmlParserTest.scala
index 131d80a7..5ddca647 100644
--- a/coverage-parser/src/test/scala/com/codacy/parsers/PhpUnitXmlParserTest.scala
+++ b/coverage-parser/src/test/scala/com/codacy/parsers/PhpUnitXmlParserTest.scala
@@ -44,15 +44,6 @@ class PhpUnitXmlParserTest extends WordSpec with BeforeAndAfterAll with Matchers
reader shouldBe 'right
}
- "return a report with the expected total coverage" in {
- val report = PhpUnitXmlParser
- .parse(new File(rootPath), new File(validReport))
- .right
- .value
-
- report.total shouldBe 69
- }
-
"return a report with the expected number of files" in {
val report = PhpUnitXmlParser
.parse(new File(rootPath), new File(validReport))
@@ -82,25 +73,6 @@ class PhpUnitXmlParserTest extends WordSpec with BeforeAndAfterAll with Matchers
).sorted
}
- "return a report with the expected file coverage" in {
- val report = PhpUnitXmlParser
- .parse(new File(rootPath), new File(validReport))
- .right
- .value
-
- report.fileReports.find(_.filename.endsWith(configPhpFile)) match {
- case None => fail(configPhpFile + " file is not present in the list of file reports")
- case Some(fileReport) =>
- fileReport.total shouldBe 86
- }
-
- report.fileReports.find(_.filename.endsWith("CloverParser.php")) match {
- case None => fail("CloverParser.php is not present in the list of file reports")
- case Some(fileReport) =>
- fileReport.total shouldBe 95
- }
- }
-
"return a report with the expected line coverage" in {
val report = PhpUnitXmlParser
.parse(new File(rootPath), new File(validReport))
diff --git a/integration-tests/mock-server-config.json b/integration-tests/mock-server-config.json
index 55c56af7..a8616ecf 100644
--- a/integration-tests/mock-server-config.json
+++ b/integration-tests/mock-server-config.json
@@ -1,6 +1,6 @@
{
"httpRequest": {
- "body": {"total":76,"fileReports":[{"filename":"app/Experiment/FooBar.cs","total":71,"coverage":{"10":1,"21":1,"9":1,"13":1,"17":1,"19":0,"15":0}},{"filename":"app/Tests/FooBarTests.cs","total":100,"coverage":{"10":1,"14":1,"29":1,"21":1,"13":1,"22":1,"27":1,"18":1,"31":1,"11":1,"26":1,"30":1,"19":1}},{"filename":"app/Experiment/Program.cs","total":0,"coverage":{"8":0,"9":0,"10":0}},{"filename":"app/Experiment/Bar.cs","total":57,"coverage":{"10":0,"14":1,"9":1,"12":0,"11":0,"8":1,"15":1}},{"filename":"app/Experiment/Foo.cs","total":100,"coverage":{"8":1,"9":1,"10":1,"11":1}}]}
+ "body": {"fileReports":[{"filename":"app/Experiment/FooBar.cs","coverage":{"10":1,"21":1,"9":1,"13":1,"17":1,"19":0,"15":0}},{"filename":"app/Tests/FooBarTests.cs","coverage":{"10":1,"14":1,"29":1,"21":1,"13":1,"22":1,"27":1,"18":1,"31":1,"11":1,"26":1,"30":1,"19":1}},{"filename":"app/Experiment/Program.cs","coverage":{"8":0,"9":0,"10":0}},{"filename":"app/Experiment/Bar.cs","coverage":{"10":0,"14":1,"9":1,"12":0,"11":0,"8":1,"15":1}},{"filename":"app/Experiment/Foo.cs","coverage":{"8":1,"9":1,"10":1,"11":1}}]}
},
"httpResponse": {
"statusCode": 200,
diff --git a/project/build.properties b/project/build.properties
index 563a014d..e8a1e246 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=1.7.2
+sbt.version=1.9.7
diff --git a/project/plugins.sbt b/project/plugins.sbt
index c656a53c..d8d127c6 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,13 +1,10 @@
-addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.1")
-addSbtPlugin("com.codacy" % "codacy-sbt-plugin" % "22.0.1")
+addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.4")
+addSbtPlugin("com.codacy" % "codacy-sbt-plugin" % "25.1.1")
// Publish
-addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
-
-// Updates
-addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.4.0")
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2")
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.4")
// Coverage
-addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.6")
-evictionErrorLevel := Level.Warn
+addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
+
+libraryDependencySchemes ++= Seq("org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always)
diff --git a/src/test/scala/com/codacy/rules/ReportRulesSpec.scala b/src/test/scala/com/codacy/rules/ReportRulesSpec.scala
index 22269f44..c88f028d 100644
--- a/src/test/scala/com/codacy/rules/ReportRulesSpec.scala
+++ b/src/test/scala/com/codacy/rules/ReportRulesSpec.scala
@@ -22,8 +22,8 @@ class ReportRulesSpec extends WordSpec with Matchers with PrivateMethodTester wi
val conf =
Report(baseConf, Some("Scala"), coverageReports = Some(coverageFiles), prefix = None, forceCoverageParser = None)
- val coverageReport = CoverageReport(100, Seq(CoverageFileReport("file.scala", 100, Map(10 -> 1))))
- val noLanguageReport = CoverageReport(0, Seq.empty[CoverageFileReport])
+ val coverageReport = CoverageReport(Seq(CoverageFileReport("file.scala", Map(10 -> 1))))
+ val noLanguageReport = CoverageReport(Seq.empty[CoverageFileReport])
val configRules = new ConfigurationRules(conf, sys.env)
val validatedConfig = configRules.validatedConfig.right.value
@@ -271,7 +271,7 @@ class ReportRulesSpec extends WordSpec with Matchers with PrivateMethodTester wi
"storeReport" should {
"not store report" in {
- val emptyReport = CoverageReport(0, Seq.empty[CoverageFileReport])
+ val emptyReport = CoverageReport(Seq.empty[CoverageFileReport])
val tempFile = File.createTempFile("storeReport", "not-store")
val result = components.reportRules.storeReport(emptyReport, tempFile)
@@ -280,7 +280,7 @@ class ReportRulesSpec extends WordSpec with Matchers with PrivateMethodTester wi
"successfully store report" when {
def storeValidReport() = {
- val emptyReport = CoverageReport(0, List(CoverageFileReport("file-name", 0, Map.empty)))
+ val emptyReport = CoverageReport(List(CoverageFileReport("file-name", Map.empty)))
val tempFile = File.createTempFile("storeReport", "not-store")
components.reportRules.storeReport(emptyReport, tempFile)
}
diff --git a/src/test/scala/com/codacy/transformation/PathPrefixerSpec.scala b/src/test/scala/com/codacy/transformation/PathPrefixerSpec.scala
index 7d7405a0..45b44b15 100644
--- a/src/test/scala/com/codacy/transformation/PathPrefixerSpec.scala
+++ b/src/test/scala/com/codacy/transformation/PathPrefixerSpec.scala
@@ -6,8 +6,7 @@ import org.scalatest._
class PathPrefixerSpec extends WordSpec with Matchers {
val report = CoverageReport(
- 83,
- Seq(CoverageFileReport("Filename.scala", 24, Map.empty), CoverageFileReport("OtherFile.scala", 74, Map.empty))
+ Seq(CoverageFileReport("Filename.scala", Map.empty), CoverageFileReport("OtherFile.scala", Map.empty))
)
"PathPrefixer" should {