Skip to content

Commit 3dcca23

Browse files
authored
Add test coverage slightly (#1523)
1 parent 5f4e704 commit 3dcca23

File tree

2 files changed

+238
-4
lines changed

2 files changed

+238
-4
lines changed

.github/workflows/main.yml

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,22 @@ jobs:
7272
token: ${{ secrets.CODECOV_TOKEN }}
7373
files: ./target/site/jacoco/jacoco.xml
7474
flags: unittests
75+
- name: Upload coverage report as artifact
76+
if: ${{ matrix.release_build && github.event_name != 'pull_request' }}
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: jacoco-report
80+
path: target/site/jacoco/jacoco.csv
81+
retention-days: 30
82+
- name: Download base branch coverage
83+
if: ${{ matrix.release_build && github.event_name == 'pull_request' }}
84+
uses: dawidd6/action-download-artifact@v6
85+
continue-on-error: true
86+
with:
87+
workflow: main.yml
88+
branch: ${{ github.event.pull_request.base.ref }}
89+
name: jacoco-report
90+
path: base-coverage/
7591
- name: Add coverage delta report to PR
7692
if: ${{ matrix.release_build && github.event_name == 'pull_request' }}
7793
uses: madrapps/jacoco-report@v1.7.1
@@ -98,6 +114,51 @@ jobs:
98114
COVERAGE=$(awk -v cov="${{ steps.jacoco.outputs.coverage }}" 'BEGIN { printf "%.1f", cov * 100 }')
99115
BRANCHES=$(awk -v br="${{ steps.jacoco.outputs.branches }}" 'BEGIN { printf "%.1f", br * 100 }')
100116
117+
# Check if base coverage artifact was downloaded
118+
if [ -f "base-coverage/jacoco.csv" ]; then
119+
echo "Found base branch coverage from artifact"
120+
BASE_CSV="base-coverage/jacoco.csv"
121+
122+
# Parse base branch coverage
123+
BASE_COVERAGE=$(awk -F',' 'NR>1 && $1=="Jackson-core" {
124+
missed=$4; covered=$5;
125+
if (missed + covered > 0) printf "%.1f", (covered * 100.0) / (missed + covered)
126+
}' "$BASE_CSV" | head -1)
127+
BASE_BRANCHES=$(awk -F',' 'NR>1 && $1=="Jackson-core" {
128+
missed=$6; covered=$7;
129+
if (missed + covered > 0) printf "%.1f", (covered * 100.0) / (missed + covered)
130+
}' "$BASE_CSV" | head -1)
131+
132+
if [ -n "$BASE_COVERAGE" ] && [ -n "$BASE_BRANCHES" ]; then
133+
# Calculate deltas
134+
COV_DELTA=$(awk -v curr="$COVERAGE" -v base="$BASE_COVERAGE" 'BEGIN { printf "%.1f", curr - base }')
135+
BR_DELTA=$(awk -v curr="$BRANCHES" -v base="$BASE_BRANCHES" 'BEGIN { printf "%.1f", curr - base }')
136+
137+
# Format delta strings with + or - signs
138+
if awk -v delta="$COV_DELTA" 'BEGIN { exit (delta >= 0) ? 0 : 1 }'; then
139+
COV_DELTA_STR="+${COV_DELTA}%"
140+
COV_DELTA_EMOJI="📈"
141+
else
142+
COV_DELTA_STR="${COV_DELTA}%"
143+
COV_DELTA_EMOJI="📉"
144+
fi
145+
146+
if awk -v delta="$BR_DELTA" 'BEGIN { exit (delta >= 0) ? 0 : 1 }'; then
147+
BR_DELTA_STR="+${BR_DELTA}%"
148+
BR_DELTA_EMOJI="📈"
149+
else
150+
BR_DELTA_STR="${BR_DELTA}%"
151+
BR_DELTA_EMOJI="📉"
152+
fi
153+
154+
HAS_DELTA=true
155+
else
156+
HAS_DELTA=false
157+
fi
158+
else
159+
HAS_DELTA=false
160+
fi
161+
101162
# Determine color for coverage badge using awk (more portable than bc)
102163
COV_COLOR=$(awk -v cov="$COVERAGE" 'BEGIN {
103164
if (cov >= 80) print "brightgreen"
@@ -113,12 +174,22 @@ jobs:
113174
else print "red"
114175
}')
115176
116-
COMMENT_BODY="## :chart_with_upwards_trend: Overall Code Coverage
117-
118-
| Metric | Coverage |
177+
# Build coverage table with or without deltas
178+
if [ "$HAS_DELTA" = "true" ]; then
179+
COVERAGE_TABLE="| Metric | Coverage | Change |
180+
|--------|----------|--------|
181+
| **Instructions** | ![coverage](https://img.shields.io/badge/coverage-${COVERAGE}%25-${COV_COLOR}) **${COVERAGE}%** | ${COV_DELTA_EMOJI} **${COV_DELTA_STR}** |
182+
| **Branches** | ![branches](https://img.shields.io/badge/branches-${BRANCHES}%25-${BR_COLOR}) **${BRANCHES}%** | ${BR_DELTA_EMOJI} **${BR_DELTA_STR}** |"
183+
else
184+
COVERAGE_TABLE="| Metric | Coverage |
119185
|--------|----------|
120186
| **Instructions** | ![coverage](https://img.shields.io/badge/coverage-${COVERAGE}%25-${COV_COLOR}) **${COVERAGE}%** |
121-
| **Branches** | ![branches](https://img.shields.io/badge/branches-${BRANCHES}%25-${BR_COLOR}) **${BRANCHES}%** |
187+
| **Branches** | ![branches](https://img.shields.io/badge/branches-${BRANCHES}%25-${BR_COLOR}) **${BRANCHES}%** |"
188+
fi
189+
190+
COMMENT_BODY="## :chart_with_upwards_trend: Overall Code Coverage
191+
192+
$COVERAGE_TABLE
122193
123194
> Overall project coverage from JaCoCo test results
124195

src/test/java/tools/jackson/core/unittest/io/NumberInputTest.java

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,167 @@ void looksLikeValidNumberFalse()
143143
assertFalse(NumberInput.looksLikeValidNumber("-E"));
144144
assertFalse(NumberInput.looksLikeValidNumber("+E"));
145145
}
146+
147+
@Test
148+
void parseIntFromCharArray()
149+
{
150+
// Test parsing integers from char arrays with various lengths
151+
// Single digit
152+
char[] ch1 = "5".toCharArray();
153+
assertEquals(5, NumberInput.parseInt(ch1, 0, 1));
154+
155+
// Two digits
156+
char[] ch2 = "42".toCharArray();
157+
assertEquals(42, NumberInput.parseInt(ch2, 0, 2));
158+
159+
// Three digits
160+
char[] ch3 = "123".toCharArray();
161+
assertEquals(123, NumberInput.parseInt(ch3, 0, 3));
162+
163+
// Four digits
164+
char[] ch4 = "1234".toCharArray();
165+
assertEquals(1234, NumberInput.parseInt(ch4, 0, 4));
166+
167+
// Five digits
168+
char[] ch5 = "12345".toCharArray();
169+
assertEquals(12345, NumberInput.parseInt(ch5, 0, 5));
170+
171+
// Six digits
172+
char[] ch6 = "123456".toCharArray();
173+
assertEquals(123456, NumberInput.parseInt(ch6, 0, 6));
174+
175+
// Seven digits
176+
char[] ch7 = "1234567".toCharArray();
177+
assertEquals(1234567, NumberInput.parseInt(ch7, 0, 7));
178+
179+
// Eight digits
180+
char[] ch8 = "12345678".toCharArray();
181+
assertEquals(12345678, NumberInput.parseInt(ch8, 0, 8));
182+
183+
// Nine digits (max for fast path)
184+
char[] ch9 = "123456789".toCharArray();
185+
assertEquals(123456789, NumberInput.parseInt(ch9, 0, 9));
186+
187+
// Test with offset
188+
char[] chOffset = "abc123def".toCharArray();
189+
assertEquals(123, NumberInput.parseInt(chOffset, 3, 3));
190+
191+
// Test with leading plus sign
192+
char[] chPlus = "+42".toCharArray();
193+
assertEquals(42, NumberInput.parseInt(chPlus, 0, 3));
194+
}
195+
196+
@Test
197+
void parseIntFromString()
198+
{
199+
// Positive numbers
200+
assertEquals(0, NumberInput.parseInt("0"));
201+
assertEquals(5, NumberInput.parseInt("5"));
202+
assertEquals(42, NumberInput.parseInt("42"));
203+
assertEquals(123, NumberInput.parseInt("123"));
204+
assertEquals(999999999, NumberInput.parseInt("999999999"));
205+
206+
// Negative numbers
207+
assertEquals(-1, NumberInput.parseInt("-1"));
208+
assertEquals(-42, NumberInput.parseInt("-42"));
209+
assertEquals(-123, NumberInput.parseInt("-123"));
210+
assertEquals(-999999999, NumberInput.parseInt("-999999999"));
211+
212+
// Boundary values
213+
assertEquals(Integer.MAX_VALUE, NumberInput.parseInt(String.valueOf(Integer.MAX_VALUE)));
214+
assertEquals(Integer.MIN_VALUE, NumberInput.parseInt(String.valueOf(Integer.MIN_VALUE)));
215+
}
216+
217+
@Test
218+
void parseLongFromCharArray()
219+
{
220+
// Test 10 digit number
221+
char[] ch10 = "1234567890".toCharArray();
222+
assertEquals(1234567890L, NumberInput.parseLong(ch10, 0, 10));
223+
224+
// Test 15 digit number
225+
char[] ch15 = "123456789012345".toCharArray();
226+
assertEquals(123456789012345L, NumberInput.parseLong(ch15, 0, 15));
227+
228+
// Test 18 digit number
229+
char[] ch18 = "123456789012345678".toCharArray();
230+
assertEquals(123456789012345678L, NumberInput.parseLong(ch18, 0, 18));
231+
}
232+
233+
@Test
234+
void parseLong19Digits()
235+
{
236+
// Test parsing exactly 19 digit numbers
237+
char[] ch19 = "1234567890123456789".toCharArray();
238+
assertEquals(1234567890123456789L, NumberInput.parseLong19(ch19, 0, false));
239+
assertEquals(-1234567890123456789L, NumberInput.parseLong19(ch19, 0, true));
240+
241+
// Test with offset
242+
char[] chOffset = "xxx9223372036854775807".toCharArray();
243+
assertEquals(9223372036854775807L, NumberInput.parseLong19(chOffset, 3, false));
244+
}
245+
246+
@Test
247+
void parseLongFromString()
248+
{
249+
// Short values (delegates to parseInt)
250+
assertEquals(0L, NumberInput.parseLong("0"));
251+
assertEquals(123L, NumberInput.parseLong("123"));
252+
assertEquals(-456L, NumberInput.parseLong("-456"));
253+
254+
// Long values
255+
assertEquals(12345678901L, NumberInput.parseLong("12345678901"));
256+
assertEquals(-12345678901L, NumberInput.parseLong("-12345678901"));
257+
258+
// Boundary values
259+
assertEquals(Long.MAX_VALUE, NumberInput.parseLong(String.valueOf(Long.MAX_VALUE)));
260+
assertEquals(Long.MIN_VALUE, NumberInput.parseLong(String.valueOf(Long.MIN_VALUE)));
261+
}
262+
263+
@Test
264+
void inLongRangeFromCharArray()
265+
{
266+
// Values clearly in range
267+
char[] small = "12345".toCharArray();
268+
assertTrue(NumberInput.inLongRange(small, 0, 5, false));
269+
assertTrue(NumberInput.inLongRange(small, 0, 5, true));
270+
271+
// Boundary testing - Long.MAX_VALUE = 9223372036854775807 (19 digits)
272+
char[] maxLong = "9223372036854775807".toCharArray();
273+
assertTrue(NumberInput.inLongRange(maxLong, 0, 19, false));
274+
275+
// Just above Long.MAX_VALUE
276+
char[] aboveMax = "9223372036854775808".toCharArray();
277+
assertFalse(NumberInput.inLongRange(aboveMax, 0, 19, false));
278+
279+
// Long.MIN_VALUE = -9223372036854775808 (19 digits without sign)
280+
char[] minLong = "9223372036854775808".toCharArray();
281+
assertTrue(NumberInput.inLongRange(minLong, 0, 19, true));
282+
283+
// Just above Long.MIN_VALUE magnitude
284+
char[] aboveMin = "9223372036854775809".toCharArray();
285+
assertFalse(NumberInput.inLongRange(aboveMin, 0, 19, true));
286+
287+
// 20 digits - always too large
288+
char[] tooLong = "12345678901234567890".toCharArray();
289+
assertFalse(NumberInput.inLongRange(tooLong, 0, 20, false));
290+
}
291+
292+
@Test
293+
void inLongRangeFromString()
294+
{
295+
// Values clearly in range
296+
assertTrue(NumberInput.inLongRange("12345", false));
297+
assertTrue(NumberInput.inLongRange("12345", true));
298+
299+
// Boundary testing
300+
assertTrue(NumberInput.inLongRange("9223372036854775807", false));
301+
assertFalse(NumberInput.inLongRange("9223372036854775808", false));
302+
303+
assertTrue(NumberInput.inLongRange("9223372036854775808", true));
304+
assertFalse(NumberInput.inLongRange("9223372036854775809", true));
305+
306+
// Too many digits
307+
assertFalse(NumberInput.inLongRange("12345678901234567890", false));
308+
}
146309
}

0 commit comments

Comments
 (0)