Skip to content

Commit

Permalink
Added report content validation test (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmazzo authored Nov 28, 2024
1 parent 6a149f3 commit 82cc9ad
Show file tree
Hide file tree
Showing 21 changed files with 2,177 additions and 1 deletion.
24 changes: 24 additions & 0 deletions .run/Update specs.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Update specs" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="collectExpectedReports" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<method v="2" />
</configuration>
</component>
64 changes: 63 additions & 1 deletion demo-project/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import com.github.difflib.DiffUtils
import com.github.difflib.UnifiedDiffUtils

buildscript {
dependencies {
classpath(libs.diffUtils)
}
}

plugins {
base
id("io.github.gmazzo.test.aggregation.results")
Expand Down Expand Up @@ -33,6 +42,59 @@ tasks.jacocoAggregatedCoverageVerification {
}
}

val aggregatedReportsSpecs = layout.projectDirectory.dir("specs/aggregated-reports")

tasks.jacocoAggregatedReport {
reports.csv.required = true
}

val reportsSpec = copySpec {
includeEmptyDirs = false
from(tasks.jacocoAggregatedReport) { include("**/*.csv") }
from(tasks.testAggregatedReport) {
into("tests")
filter { if (it.startsWith("<a href=\"http://www.gradle.org\">")) "" else it }
}
}

tasks.register<Sync>("collectExpectedReports") {
with(reportsSpec)
into(aggregatedReportsSpecs)
}

val checkAggregatedReportsContent by tasks.registering(Sync::class) {
with(reportsSpec) { into("actual") }
into(temporaryDir)
doLast {
fun File.collect() = walkTopDown()
.filter(File::isFile)
.associateBy { it.toRelativeString(this) }

val expected = File(temporaryDir, "expects").collect()
val actual = File(temporaryDir, "actual").collect()
val diff = (expected.keys + actual.keys).mapNotNull {
val expectedLines = expected[it]?.readLines().orEmpty()
val actualLines = actual[it]?.readLines().orEmpty()

when (actualLines) {
expectedLines -> null
else -> UnifiedDiffUtils.generateUnifiedDiff(
"expected:${it}", "actual:${it}",
expectedLines,
DiffUtils.diff(expectedLines, actualLines),
3
)
}
}
check(diff.isEmpty()) {
diff.joinToString(
prefix = "The generated reports are different than the expected ones:\n",
separator = "\n\n\n"
)
}
}
}

tasks.check {
dependsOn(tasks.jacocoAggregatedCoverageVerification)
dependsOn(tasks.jacocoAggregatedCoverageVerification, checkAggregatedReportsContent)
}
32 changes: 32 additions & 0 deletions demo-project/specs/aggregated-reports/jacocoAggregatedReport.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
GROUP,PACKAGE,CLASS,INSTRUCTION_MISSED,INSTRUCTION_COVERED,BRANCH_MISSED,BRANCH_COVERED,LINE_MISSED,LINE_COVERED,COMPLEXITY_MISSED,COMPLEXITY_COVERED,METHOD_MISSED,METHOD_COVERED
demo-project,com.example.myapplication,SecondFragment,48,0,0,0,12,0,6,0,6,0
demo-project,com.example.myapplication,FirstFragment,6,42,0,0,2,10,1,5,1,5
demo-project,com.example.myapplication,MainActivity.onPostCreate..inlined.AppBarConfiguration.default.new Function0() {...},3,0,0,0,1,0,1,0,1,0
demo-project,com.example.myapplication,MainActivity,29,48,4,0,6,10,4,2,2,2
demo-project,com.example.login.databinding,ActivityLoginBinding,109,0,10,0,34,0,10,0,5,0
demo-project,com.example.kmp,KMPObjectAndroid,0,9,0,0,0,1,0,2,0,2
demo-project,com.example.kmp,KMPObject,0,9,0,0,0,1,0,2,0,2
demo-project,com.example.kmp,MoshiObjAndroidJsonAdapter,173,0,16,0,29,0,13,0,4,0
demo-project,com.example.kmp,KMPObjectJVM,0,9,0,0,0,1,0,2,0,2
demo-project,com.example.kmp,MoshiObjJVMJsonAdapter,173,0,16,0,29,0,13,0,4,0
demo-project,com.example.kmp,MoshiObjJVM,21,0,0,0,3,0,3,0,3,0
demo-project,com.example.kmp,MoshiObjAndroid,21,0,0,0,3,0,3,0,3,0
demo-project,com.example.kmp,PlatformKt,0,5,0,0,0,1,0,2,0,2
demo-project,com.example.domain,MyUseCase,0,5,0,0,0,2,0,2,0,2
demo-project,com.example.login.ui.login,LoginViewModel,162,0,12,0,21,0,13,0,7,0
demo-project,com.example.login.ui.login,LoginActivityKt.afterTextChanged.new TextWatcher() {...},21,0,0,0,5,0,4,0,4,0
demo-project,com.example.login.ui.login,LoginActivityKt,14,0,0,0,2,0,1,0,1,0
demo-project,com.example.login.ui.login,LoggedInUserView,12,0,0,0,2,0,2,0,2,0
demo-project,com.example.login.ui.login,LoginActivity,269,0,14,0,62,0,17,0,10,0
demo-project,com.example.login.ui.login,LoginViewModelFactory,26,0,2,0,6,0,3,0,2,0
demo-project,com.example.login.ui.login,LoginFormState,42,0,0,0,5,0,5,0,5,0
demo-project,com.example.login.ui.login,LoginResult,30,0,0,0,4,0,4,0,4,0
demo-project,com.example.login.ui.data,Result,18,0,2,0,3,0,2,0,1,0
demo-project,com.example.login.ui.data,Result.Success,0,13,0,0,0,1,0,2,0,2
demo-project,com.example.login.ui.data,LoginRepository,61,0,4,0,15,0,9,0,7,0
demo-project,com.example.login.ui.data,Result.Error,13,0,0,0,1,0,2,0,2,0
demo-project,com.example.login.ui.data,LoginDataSource,13,26,0,0,3,4,1,2,1,2
demo-project,com.example.login.ui.data.model,LoggedInUser,3,18,0,0,0,3,1,2,1,2
demo-project,com.example.myapplication.databinding,FragmentFirstBinding,22,52,3,3,6,16,4,4,1,4
demo-project,com.example.myapplication.databinding,FragmentSecondBinding,74,0,6,0,22,0,8,0,5,0
demo-project,com.example.myapplication.databinding,ActivityMainBinding,17,57,3,3,5,17,3,5,0,5
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class MyUseCaseTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class MyUseCaseTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/default-package.html">default-package</a> &gt; MyUseCaseTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">1</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.008s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">testIsDone</td>
<td class="success">0.008s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by

</div>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class com.example.kmp.KMPObjectAndroidTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class com.example.kmp.KMPObjectAndroidTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.example.kmp.html">com.example.kmp</a> &gt; KMPObjectAndroidTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.067s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">testKMPObject</td>
<td class="success">0.034s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">testKMPObject</td>
<td class="success">0.033s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by

</div>
</div>
</body>
</html>
Loading

0 comments on commit 82cc9ad

Please sign in to comment.