Skip to content

Commit 15db9c5

Browse files
committed
Add JaCoCo coverage to Ant and GitHub Actions; expand unit tests.
Wire JaCoCo 0.8.14 into build.xml (test-coverage, coverage-report) with HTML, XML, CSV reports and an Ant XSLT text summary; copy report.dtd from jacocoant.jar so XSLT can parse coverage.xml. Exclude jacocoant from runtime and test classpaths. Update vstar-UT workflow to run coverage-report, upload artifacts, and use current checkout/setup-java actions with Temurin. Document JaCoCo in extlib/ReadMe.txt. Add focused unit tests for notification, util helpers, data types, comment codes, filters, comparators, exceptions, auth JSON parsing, UTF8 stream filter, ObservationSourceAnalyser, Harmonic, and PeriodFitParameters. Made-with: Cursor
1 parent 155151d commit 15db9c5

20 files changed

+1802
-8
lines changed

.github/workflows/vstar-UT.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,27 @@ jobs:
1818
matrix:
1919
java: [ '17', '21', '23' ]
2020

21-
name: Java ${{ matrix.Java }} VStar UTs
21+
name: Java ${{ matrix.java }} VStar UTs
2222

2323
steps:
24-
- uses: actions/checkout@v2
24+
- uses: actions/checkout@v4
2525
- name: Set up Java
26-
uses: actions/setup-java@v1
26+
uses: actions/setup-java@v4
2727
with:
2828
java-version: ${{ matrix.java }}
29+
distribution: 'temurin'
2930
- name: Create plugin dir
3031
run:
3132
mkdir -p ~/vstar_plugins
3233
- name: Create plugin libs dir
3334
run:
3435
mkdir -p ~/vstar_plugin_libs
35-
- name: Build with Ant
36+
- name: Run tests with coverage
3637
run:
37-
ant -noinput -buildfile build.xml test
38+
ant -noinput -buildfile build.xml coverage-report
39+
- name: Upload coverage report
40+
if: always()
41+
uses: actions/upload-artifact@v4
42+
with:
43+
name: coverage-report-java${{ matrix.java }}
44+
path: test_report/coverage/

build.xml

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<project name="VStar" default="dist" basedir=".">
1+
<project name="VStar" default="dist" basedir="."
2+
xmlns:jacoco="antlib:org.jacoco.ant">
23
<description>
34
Ant build file for VStar.
45
</description>
@@ -27,18 +28,19 @@
2728
<property name="extlib" location="extlib" />
2829
<property name="ui_resources" location="src/org/aavso/tools/vstar/ui/resources" />
2930
<property name="test_report" location="test_report" />
31+
<property name="coverage_report" location="test_report/coverage" />
3032
<property name="doc" location="doc" />
3133
<property name="javadoc" location="doc/vstar_docs" />
3234
<property name="mac_identity" value="P433N2A49C" />
3335

3436
<!-- Classpaths -->
3537

3638
<path id="build.classpath">
37-
<fileset dir="${extlib}" includes="*.jar" excludes="junit*.jar,hamcrest*.jar,testng*.jar,quicktheories*.jar,pitest*.jar" />
39+
<fileset dir="${extlib}" includes="*.jar" excludes="junit*.jar,hamcrest*.jar,testng*.jar,quicktheories*.jar,pitest*.jar,jacocoant.jar" />
3840
</path>
3941

4042
<path id="test.classpath">
41-
<fileset dir="${extlib}" includes="*.jar" />
43+
<fileset dir="${extlib}" includes="*.jar" excludes="jacocoant.jar" />
4244
<pathelement location="${dist}/vstar.jar" />
4345
<pathelement path="${test_build}" />
4446
</path>
@@ -54,6 +56,10 @@
5456

5557
<taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pitest.classpath" />
5658

59+
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
60+
<classpath path="${extlib}/jacocoant.jar" />
61+
</taskdef>
62+
5763
<target name="init">
5864
<!-- Create the time stamp -->
5965
<tstamp>
@@ -398,6 +404,94 @@
398404
</fail>
399405
</target>
400406

407+
<target name="test-coverage" depends="compile_ut" description="Run unit tests with JaCoCo coverage">
408+
<jacoco:coverage destfile="${test_report}/jacoco.exec">
409+
<junit fork="yes" printsummary="withOutAndErr" showoutput="true" timeout="1800000">
410+
<formatter type="plain" />
411+
412+
<jvmarg value="-ea" />
413+
414+
<formatter type="plain" />
415+
416+
<batchtest todir="${test_report}" unless="testcase">
417+
<fileset dir="${test}">
418+
<include name="org/**/*Test.java" />
419+
</fileset>
420+
</batchtest>
421+
422+
<classpath refid="test.classpath" />
423+
</junit>
424+
</jacoco:coverage>
425+
</target>
426+
427+
<target name="coverage-report" depends="test-coverage" description="Generate JaCoCo coverage report (HTML + XML)">
428+
<mkdir dir="${coverage_report}" />
429+
<jacoco:report>
430+
<executiondata>
431+
<file file="${test_report}/jacoco.exec" />
432+
</executiondata>
433+
<structure name="VStar">
434+
<classfiles>
435+
<fileset dir="${src_build}" />
436+
</classfiles>
437+
<sourcefiles encoding="UTF-8">
438+
<fileset dir="${src}" />
439+
</sourcefiles>
440+
</structure>
441+
<html destdir="${coverage_report}" />
442+
<xml destfile="${coverage_report}/coverage.xml" />
443+
<csv destfile="${coverage_report}/coverage.csv" />
444+
</jacoco:report>
445+
<echo message="Coverage report: ${coverage_report}/index.html" />
446+
447+
<!-- JaCoCo XML references report.dtd; Ant's XSLT parser needs it beside coverage.xml -->
448+
<property name="jacoco.report.dtd.tmp" location="${coverage_report}/jacoco-dtd-extract" />
449+
<delete dir="${jacoco.report.dtd.tmp}" />
450+
<mkdir dir="${jacoco.report.dtd.tmp}" />
451+
<unzip src="${extlib}/jacocoant.jar" dest="${jacoco.report.dtd.tmp}">
452+
<patternset>
453+
<include name="org/jacoco/report/xml/report.dtd" />
454+
</patternset>
455+
</unzip>
456+
<copy file="${jacoco.report.dtd.tmp}/org/jacoco/report/xml/report.dtd" tofile="${coverage_report}/report.dtd" />
457+
<delete dir="${jacoco.report.dtd.tmp}" />
458+
459+
<!-- Text coverage summary -->
460+
<xslt in="${coverage_report}/coverage.xml"
461+
out="${coverage_report}/summary.txt"
462+
style="script/coverage_summary.xsl" />
463+
<concat>
464+
<fileset file="${coverage_report}/summary.txt" />
465+
</concat>
466+
467+
<!-- Generate summary and fail on test errors/failures -->
468+
<concat destfile="${test_report}/summary.txt">
469+
<header filtering="no" trimleading="yes">
470+
Test Summary
471+
============
472+
</header>
473+
<path>
474+
<fileset dir="${test_report}" includes="TEST-org*" />
475+
</path>
476+
<filterchain>
477+
<linecontains>
478+
<contains value="Tests run:" />
479+
</linecontains>
480+
</filterchain>
481+
</concat>
482+
483+
<exec command="cat ${test_report}/summary.txt" />
484+
485+
<fileset id="coverage.build.failures" file="${test_report}/summary.txt">
486+
<containsregexp expression="(Errors|Failures): [123456789]+" />
487+
</fileset>
488+
<fail status="1" message="One or more failures detected">
489+
<condition>
490+
<resourcecount when="greater" count="0" refid="coverage.build.failures" />
491+
</condition>
492+
</fail>
493+
</target>
494+
401495
<target name="pit" depends="test">
402496
<path id="mutation.path">
403497
<path refid="pitest.classpath" />
@@ -436,6 +530,8 @@
436530
<fileset file="*.exe" />
437531
<fileset file="*.bat" />
438532
<fileset dir="${mutation_coverage_dir}" />
533+
<fileset dir="${coverage_report}" />
534+
<fileset file="${test_report}/jacoco.exec" />
439535
</delete>
440536
</target>
441537
</project>

extlib/ReadMe.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ as part of a VStar release.
7373
- quicktheories-0.26.jar
7474
- https://github.com/quicktheories/QuickTheories
7575

76+
For line and branch coverage reporting, JaCoCo is used.
77+
78+
o JaCoCo code coverage library
79+
- https://www.jacoco.org/jacoco/
80+
- jacocoant.jar (0.8.14)
81+
- Eclipse Public License 2.0
82+
7683
For mutation testing, additional libraries are required.
7784

7885
o pitest mutation testing framework

extlib/jacocoant.jar

810 KB
Binary file not shown.

script/coverage_summary.xsl

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xsl:stylesheet version="1.0"
3+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4+
5+
<xsl:output method="text" encoding="UTF-8"/>
6+
7+
<xsl:variable name="pad" select="' '"/>
8+
<xsl:variable name="dashes" select="'--------------------------------------------------'"/>
9+
10+
<xsl:template name="right-pad">
11+
<xsl:param name="str"/>
12+
<xsl:param name="width"/>
13+
<xsl:value-of select="substring(concat($str, $pad), 1, $width)"/>
14+
</xsl:template>
15+
16+
<xsl:template name="left-pad">
17+
<xsl:param name="str"/>
18+
<xsl:param name="width"/>
19+
<xsl:value-of select="substring(concat($pad, $str), string-length(concat($pad, $str)) - $width + 1)"/>
20+
</xsl:template>
21+
22+
<xsl:template name="pct">
23+
<xsl:param name="missed"/>
24+
<xsl:param name="covered"/>
25+
<xsl:variable name="total" select="$missed + $covered"/>
26+
<xsl:choose>
27+
<xsl:when test="$total &gt; 0">
28+
<xsl:value-of select="format-number($covered div $total * 100, '0.0')"/>
29+
<xsl:text>%</xsl:text>
30+
</xsl:when>
31+
<xsl:otherwise>
32+
<xsl:text> n/a</xsl:text>
33+
</xsl:otherwise>
34+
</xsl:choose>
35+
</xsl:template>
36+
37+
<xsl:template name="header-row">
38+
<xsl:call-template name="right-pad"><xsl:with-param name="str" select="'Package'"/><xsl:with-param name="width" select="50"/></xsl:call-template>
39+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Lines'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
40+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Line%'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
41+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Branch'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
42+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Brch%'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
43+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Method'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
44+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'Mthd%'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
45+
<xsl:text>&#10;</xsl:text>
46+
</xsl:template>
47+
48+
<xsl:template name="separator-row">
49+
<xsl:call-template name="right-pad"><xsl:with-param name="str" select="$dashes"/><xsl:with-param name="width" select="50"/></xsl:call-template>
50+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
51+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
52+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
53+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
54+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
55+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="'------'"/><xsl:with-param name="width" select="7"/></xsl:call-template>
56+
<xsl:text>&#10;</xsl:text>
57+
</xsl:template>
58+
59+
<xsl:template name="data-row">
60+
<xsl:param name="label"/>
61+
<xsl:param name="line-m"/><xsl:param name="line-c"/>
62+
<xsl:param name="branch-m"/><xsl:param name="branch-c"/>
63+
<xsl:param name="method-m"/><xsl:param name="method-c"/>
64+
65+
<xsl:call-template name="right-pad"><xsl:with-param name="str" select="$label"/><xsl:with-param name="width" select="50"/></xsl:call-template>
66+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="$line-m + $line-c"/><xsl:with-param name="width" select="7"/></xsl:call-template>
67+
<xsl:call-template name="left-pad">
68+
<xsl:with-param name="str"><xsl:call-template name="pct"><xsl:with-param name="missed" select="$line-m"/><xsl:with-param name="covered" select="$line-c"/></xsl:call-template></xsl:with-param>
69+
<xsl:with-param name="width" select="7"/>
70+
</xsl:call-template>
71+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="$branch-m + $branch-c"/><xsl:with-param name="width" select="7"/></xsl:call-template>
72+
<xsl:call-template name="left-pad">
73+
<xsl:with-param name="str"><xsl:call-template name="pct"><xsl:with-param name="missed" select="$branch-m"/><xsl:with-param name="covered" select="$branch-c"/></xsl:call-template></xsl:with-param>
74+
<xsl:with-param name="width" select="7"/>
75+
</xsl:call-template>
76+
<xsl:call-template name="left-pad"><xsl:with-param name="str" select="$method-m + $method-c"/><xsl:with-param name="width" select="7"/></xsl:call-template>
77+
<xsl:call-template name="left-pad">
78+
<xsl:with-param name="str"><xsl:call-template name="pct"><xsl:with-param name="missed" select="$method-m"/><xsl:with-param name="covered" select="$method-c"/></xsl:call-template></xsl:with-param>
79+
<xsl:with-param name="width" select="7"/>
80+
</xsl:call-template>
81+
<xsl:text>&#10;</xsl:text>
82+
</xsl:template>
83+
84+
<xsl:template match="/report">
85+
<xsl:text>&#10;VStar Coverage Summary&#10;</xsl:text>
86+
<xsl:text>======================&#10;&#10;</xsl:text>
87+
88+
<xsl:call-template name="header-row"/>
89+
<xsl:call-template name="separator-row"/>
90+
91+
<xsl:for-each select="package">
92+
<xsl:variable name="short" select="translate(@name, '/', '.')"/>
93+
<xsl:variable name="label">
94+
<xsl:choose>
95+
<xsl:when test="starts-with($short, 'org.aavso.tools.vstar.')">
96+
<xsl:value-of select="concat('..', substring-after($short, 'org.aavso.tools.vstar'))"/>
97+
</xsl:when>
98+
<xsl:otherwise><xsl:value-of select="$short"/></xsl:otherwise>
99+
</xsl:choose>
100+
</xsl:variable>
101+
102+
<xsl:call-template name="data-row">
103+
<xsl:with-param name="label" select="$label"/>
104+
<xsl:with-param name="line-m" select="counter[@type='LINE']/@missed"/>
105+
<xsl:with-param name="line-c" select="counter[@type='LINE']/@covered"/>
106+
<xsl:with-param name="branch-m" select="counter[@type='BRANCH']/@missed"/>
107+
<xsl:with-param name="branch-c" select="counter[@type='BRANCH']/@covered"/>
108+
<xsl:with-param name="method-m" select="counter[@type='METHOD']/@missed"/>
109+
<xsl:with-param name="method-c" select="counter[@type='METHOD']/@covered"/>
110+
</xsl:call-template>
111+
</xsl:for-each>
112+
113+
<xsl:call-template name="separator-row"/>
114+
115+
<xsl:call-template name="data-row">
116+
<xsl:with-param name="label" select="'TOTAL'"/>
117+
<xsl:with-param name="line-m" select="counter[@type='LINE']/@missed"/>
118+
<xsl:with-param name="line-c" select="counter[@type='LINE']/@covered"/>
119+
<xsl:with-param name="branch-m" select="counter[@type='BRANCH']/@missed"/>
120+
<xsl:with-param name="branch-c" select="counter[@type='BRANCH']/@covered"/>
121+
<xsl:with-param name="method-m" select="counter[@type='METHOD']/@missed"/>
122+
<xsl:with-param name="method-c" select="counter[@type='METHOD']/@covered"/>
123+
</xsl:call-template>
124+
125+
<xsl:text>&#10;</xsl:text>
126+
</xsl:template>
127+
128+
</xsl:stylesheet>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* VStar: a statistical analysis tool for variable star data.
3+
* Copyright (C) 2010 AAVSO (http://www.aavso.org/)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as
7+
* published by the Free Software Foundation, either version 3 of the
8+
* License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package org.aavso.tools.vstar.auth;
19+
20+
import java.util.Map;
21+
22+
import junit.framework.TestCase;
23+
24+
public class Auth0JSONParserTest extends TestCase {
25+
26+
public Auth0JSONParserTest(String name) {
27+
super(name);
28+
}
29+
30+
public void testSimpleKeyValue() {
31+
Map<String, String> m = Auth0JSONAutheticationSource
32+
.parseJSONString("{\"key\": \"value\"}");
33+
assertEquals("value", m.get("key"));
34+
}
35+
36+
public void testMultipleKeyValues() {
37+
Map<String, String> m = Auth0JSONAutheticationSource
38+
.parseJSONString("{\"a\": \"1\", \"b\": \"2\"}");
39+
assertEquals("1", m.get("a"));
40+
assertEquals("2", m.get("b"));
41+
}
42+
43+
public void testBooleanValue() {
44+
Map<String, String> m = Auth0JSONAutheticationSource
45+
.parseJSONString("{\"is_member\": true}");
46+
assertEquals("true", m.get("is_member"));
47+
}
48+
49+
public void testNumericValue() {
50+
Map<String, String> m = Auth0JSONAutheticationSource
51+
.parseJSONString("{\"user_id\": 8}");
52+
assertEquals("8", m.get("user_id"));
53+
}
54+
55+
public void testWithWhitespace() {
56+
Map<String, String> m = Auth0JSONAutheticationSource
57+
.parseJSONString(" { \"a\" : \"1\" , \"b\" : \"2\" } ");
58+
assertEquals("1", m.get("a"));
59+
assertEquals("2", m.get("b"));
60+
}
61+
62+
public void testRealWorldResponse() {
63+
String json = "{\"is_member\": true, \"user_id\": 8, \"obscode\": \"BDJB\", \"email\": \"test@test.org\", \"token\": \"abc123\"}";
64+
Map<String, String> m = Auth0JSONAutheticationSource
65+
.parseJSONString(json);
66+
assertEquals("true", m.get("is_member"));
67+
assertEquals("8", m.get("user_id"));
68+
assertEquals("BDJB", m.get("obscode"));
69+
assertEquals("test@test.org", m.get("email"));
70+
assertEquals("abc123", m.get("token"));
71+
}
72+
}

0 commit comments

Comments
 (0)