-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'RadoBuransky/sonar-scoverage-plugin/mas…
…ter' into staging
- Loading branch information
Showing
56 changed files
with
3,178 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
plugin/src/main/resources/com/buransky/plugins/scoverage/widget.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<% measure=measure('scoverage') | ||
if measure | ||
%> | ||
<div class="dashbox"> | ||
<h3> | ||
Statement coverage : <%= format_measure(measure, :suffix => ' %') %> | ||
<%= dashboard_configuration.selected_period? ? format_variation(measure) : trend_icon(measure) -%> | ||
</h3> | ||
</div> | ||
<% end %> |
22 changes: 22 additions & 0 deletions
22
plugin/src/main/scala/com/buransky/plugins/scoverage/ScoverageExtensionProvider.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.buransky.plugins.scoverage | ||
|
||
import com.buransky.plugins.scoverage.language.Scala | ||
import org.sonar.api.resources.Languages | ||
import org.sonar.api.{Extension, ExtensionProvider, ServerExtension} | ||
|
||
import scala.collection.JavaConversions._ | ||
import scala.collection.mutable.ListBuffer | ||
|
||
class ScoverageExtensionProvider(languages: Languages) extends ExtensionProvider with ServerExtension { | ||
override def provide(): java.util.List[Class[_ <: Extension]] = { | ||
val result = ListBuffer[Class[_ <: Extension]]() | ||
|
||
if (languages.get(Scala.key) == null) { | ||
// Fix issue with multiple Scala plugins: | ||
// https://github.com/RadoBuransky/sonar-scoverage-plugin/issues/31 | ||
result += classOf[Scala] | ||
} | ||
|
||
result | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
plugin/src/main/scala/com/buransky/plugins/scoverage/ScoveragePlugin.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Sonar Scoverage Plugin | ||
* Copyright (C) 2013 Rado Buransky | ||
* [email protected] | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package com.buransky.plugins.scoverage | ||
|
||
import com.buransky.plugins.scoverage.measure.ScalaMetrics | ||
import com.buransky.plugins.scoverage.sensor.ScoverageSensor | ||
import com.buransky.plugins.scoverage.widget.ScoverageWidget | ||
import org.sonar.api.{Extension, SonarPlugin} | ||
|
||
import scala.collection.JavaConversions._ | ||
import scala.collection.mutable.ListBuffer | ||
|
||
/** | ||
* Plugin entry point. | ||
* | ||
* @author Rado Buransky | ||
*/ | ||
class ScoveragePlugin extends SonarPlugin { | ||
override def getExtensions: java.util.List[Class[_ <: Extension]] = | ||
ListBuffer( | ||
classOf[ScoverageExtensionProvider], | ||
classOf[ScalaMetrics], | ||
classOf[ScoverageSensor], | ||
classOf[ScoverageWidget] | ||
) | ||
|
||
override val toString = getClass.getSimpleName | ||
} |
39 changes: 39 additions & 0 deletions
39
plugin/src/main/scala/com/buransky/plugins/scoverage/ScoverageReportParser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Sonar Scoverage Plugin | ||
* Copyright (C) 2013 Rado Buransky | ||
* [email protected] | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package com.buransky.plugins.scoverage | ||
|
||
import com.buransky.plugins.scoverage.pathcleaner.PathSanitizer | ||
|
||
/** | ||
* Interface for Scoverage report parser. | ||
* | ||
* @author Rado Buransky | ||
*/ | ||
trait ScoverageReportParser { | ||
def parse(reportFilePath: String, pathSanitizer: PathSanitizer): ProjectStatementCoverage | ||
} | ||
|
||
/** | ||
* Common Scoverage exception. | ||
* | ||
* @author Rado Buransky | ||
*/ | ||
case class ScoverageException(message: String, source: Throwable = null) | ||
extends Exception(message, source) |
145 changes: 145 additions & 0 deletions
145
plugin/src/main/scala/com/buransky/plugins/scoverage/StatementCoverage.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* Sonar Scoverage Plugin | ||
* Copyright (C) 2013 Rado Buransky | ||
* [email protected] | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package com.buransky.plugins.scoverage | ||
|
||
/** | ||
* Statement coverage represents rate at which are statements of a certain source code unit | ||
* being covered by tests. | ||
* | ||
* @author Rado Buransky | ||
*/ | ||
sealed trait StatementCoverage { | ||
/** | ||
* Percentage rate ranging from 0 up to 100%. | ||
*/ | ||
lazy val rate: Double = | ||
if (statementCount == 0) | ||
0.0 | ||
else | ||
(coveredStatementsCount.toDouble / statementCount.toDouble) * 100.0 | ||
|
||
/** | ||
* Total number of all statements within the source code unit, | ||
*/ | ||
def statementCount: Int | ||
|
||
/** | ||
* Number of statements covered by unit tests. | ||
*/ | ||
def coveredStatementsCount: Int | ||
|
||
require(statementCount >= 0, "Statements count cannot be negative! [" + statementCount + "]") | ||
require(coveredStatementsCount >= 0, "Statements count cannot be negative! [" + | ||
coveredStatementsCount + "]") | ||
require(coveredStatementsCount <= statementCount, | ||
"Number of covered statements cannot be more than total number of statements! [" + | ||
statementCount + ", " + coveredStatementsCount + "]") | ||
} | ||
|
||
/** | ||
* Allows to build tree structure from state coverage values. | ||
*/ | ||
trait NodeStatementCoverage extends StatementCoverage { | ||
def name: String | ||
def children: Iterable[NodeStatementCoverage] | ||
def statementSum: Int = children.map(_.statementSum).sum | ||
def coveredStatementsSum: Int = children.map(_.coveredStatementsSum).sum | ||
} | ||
|
||
/** | ||
* Root node. In multi-module projects it can contain other ProjectStatementCoverage | ||
* elements as children. | ||
*/ | ||
case class ProjectStatementCoverage(name: String, children: Iterable[NodeStatementCoverage]) | ||
extends NodeStatementCoverage { | ||
// projects' coverage values are defined as sums of their child values | ||
val statementCount = statementSum | ||
val coveredStatementsCount = coveredStatementsSum | ||
} | ||
|
||
/** | ||
* Physical directory in file system. | ||
*/ | ||
case class DirectoryStatementCoverage(name: String, children: Iterable[NodeStatementCoverage]) | ||
extends NodeStatementCoverage { | ||
// directories' coverage values are defined as sums of their DIRECT child values | ||
val statementCount = children.filter(_.isInstanceOf[FileStatementCoverage]).map(_.statementCount).sum | ||
val coveredStatementsCount = children.filter(_.isInstanceOf[FileStatementCoverage]).map(_.coveredStatementsCount).sum | ||
} | ||
|
||
/** | ||
* Scala source code file. | ||
*/ | ||
case class FileStatementCoverage(name: String, statementCount: Int, coveredStatementsCount: Int, | ||
statements: Iterable[CoveredStatement]) extends NodeStatementCoverage { | ||
// leaf implementation sums==values | ||
val children = List.empty[NodeStatementCoverage] | ||
override val statementSum = statementCount | ||
override val coveredStatementsSum = coveredStatementsCount | ||
} | ||
|
||
/** | ||
* Position a Scala source code file. | ||
*/ | ||
case class StatementPosition(line: Int, pos: Int) | ||
|
||
/** | ||
* Coverage information about the Scala statement. | ||
* | ||
* @param start Starting position of the statement. | ||
* @param end Ending position of the statement. | ||
* @param hitCount How many times has the statement been hit by unit tests. Zero means | ||
* that the statement is not covered. | ||
*/ | ||
case class CoveredStatement(start: StatementPosition, end: StatementPosition, hitCount: Int) | ||
|
||
/** | ||
* Aggregated statement coverage for a given source code line. | ||
*/ | ||
case class CoveredLine(line: Int, hitCount: Int) | ||
|
||
object StatementCoverage { | ||
/** | ||
* Utility method to transform statement coverage to line coverage. Pessimistic logic is used | ||
* meaning that line hit count is minimum of hit counts of all statements on the given line. | ||
* | ||
* Example: If a line contains two statements, one is covered by 3 hits, the other one is | ||
* without any hits, then the whole line is treated as uncovered. | ||
* | ||
* @param statements Statement coverage. | ||
* @return Line coverage. | ||
*/ | ||
def statementCoverageToLineCoverage(statements: Iterable[CoveredStatement]): Iterable[CoveredLine] = { | ||
// Handle statements that end on a different line than start | ||
val multilineStatements = statements.filter { s => s.start.line != s.end.line } | ||
val extraStatements = multilineStatements.flatMap { s => | ||
for (i <- (s.start.line + 1) to s.end.line) | ||
yield CoveredStatement(StatementPosition(i, 0), StatementPosition(i, 0), s.hitCount) | ||
} | ||
|
||
// Group statements by starting line | ||
val lineStatements = (statements ++ extraStatements).groupBy(_.start.line) | ||
|
||
// Pessimistic approach: line hit count is a minimum of hit counts of all statements on the line | ||
lineStatements.map { lineStatement => | ||
CoveredLine(lineStatement._1, lineStatement._2.map(_.hitCount).min) | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
plugin/src/main/scala/com/buransky/plugins/scoverage/language/Scala.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Sonar Scoverage Plugin | ||
* Copyright (C) 2013 Rado Buransky | ||
* [email protected] | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package com.buransky.plugins.scoverage.language | ||
|
||
import org.sonar.api.resources.AbstractLanguage | ||
|
||
/** | ||
* Scala language. | ||
* | ||
* @author Rado Buransky | ||
*/ | ||
class Scala extends AbstractLanguage(Scala.key, Scala.name) { | ||
val getFileSuffixes = Array(Scala.fileExtension) | ||
} | ||
|
||
object Scala { | ||
val key = "scala" | ||
val name = "Scala" | ||
val fileExtension = "scala" | ||
} |
Oops, something went wrong.