From e9b74a1d9b418a0f8a86fac88371eaa02e9f4f77 Mon Sep 17 00:00:00 2001
From: loong10k <20489781+loong10k@users.noreply.github.com>
Date: Wed, 4 Nov 2026 08:38:55 +0800
Subject: [PATCH] fix: run real compression and JUnit3 tests on Java 17 CI
---
.github/scripts/verify-test-reports.py | 26 +++++++++++
.github/workflows/ci.yml | 18 +++-----
pom.xml | 15 +++----
.../yui/compressor/CompressionTest.java | 45 +++++++++++++++++++
4 files changed, 83 insertions(+), 21 deletions(-)
create mode 100644 .github/scripts/verify-test-reports.py
create mode 100644 src/test/java/com/yahoo/platform/yui/compressor/CompressionTest.java
diff --git a/.github/scripts/verify-test-reports.py b/.github/scripts/verify-test-reports.py
new file mode 100644
index 0000000..98aa65c
--- /dev/null
+++ b/.github/scripts/verify-test-reports.py
@@ -0,0 +1,26 @@
+"""Reject missing, empty, failed, skipped, duplicate or incomplete test reports."""
+from pathlib import Path
+import xml.etree.ElementTree as ET
+
+reports = list(Path('target/surefire-reports').glob('TEST-*.xml'))
+assert reports, 'No Surefire XML reports found'
+expected = {
+ 'jargs.test.gnu.CmdLineParserTestCase': 11,
+ 'jargs.test.gnu.CustomOptionTestCase': 2,
+ 'com.yahoo.platform.yui.compressor.CompressionTest': 4,
+}
+seen = set()
+counts = {}
+for report in reports:
+ suite = ET.parse(report).getroot()
+ cases = suite.findall('testcase')
+ assert cases, f'Empty test report: {report}'
+ for case in cases:
+ key = (case.attrib['classname'], case.attrib['name'])
+ assert key not in seen, f'Duplicate test: {key}'
+ assert not any(case.find(tag) is not None for tag in ('failure', 'error', 'skipped')), key
+ seen.add(key)
+ counts[key[0]] = counts.get(key[0], 0) + 1
+for name, minimum in expected.items():
+ assert counts.get(name, 0) >= minimum, f'Missing tests in {name}: {counts.get(name, 0)} < {minimum}'
+print(f'Verified {len(seen)} unique passing tests across {len(reports)} reports')
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9663666..dd001c8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,15 +1,3 @@
-# CI workflow for easy4j Spring Boot Starter
-#
-# Triggers:
-# - push / pull_request on all version-line branches
-# - manual workflow_dispatch
-#
-# JDK matrix by version line:
-# - 2.3.x / 2.7.x : JDK 8
-# - 3.0.x ~ 3.5.x : JDK 17
-# - 4.0.x / 4.1.x : JDK 17 / 21
-#
-# Runs `mvn -B clean verify` with dependency convergence checks.
name: CI
on:
@@ -30,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- java: [8, 17, 21]
+ java: [17, 21]
steps:
- name: Checkout source
uses: actions/checkout@v4
@@ -45,6 +33,9 @@ jobs:
- name: Build and verify
run: mvn -B --no-transfer-progress clean verify
+ - name: Verify test reports
+ run: python3 .github/scripts/verify-test-reports.py
+
- name: Upload surefire reports
if: always()
uses: actions/upload-artifact@v4
@@ -52,3 +43,4 @@ jobs:
name: surefire-reports-jdk${{ matrix.java }}
path: target/surefire-reports
retention-days: 14
+ if-no-files-found: error
diff --git a/pom.xml b/pom.xml
index 314f1d9..1d481b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -127,22 +127,21 @@
maven-surefire-plugin
2.19.1
-
- true
- true
-
- once
- -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -Dfile.encoding=UTF-8
+ true
+ -Xmx1024m -Dfile.encoding=UTF-8
${basedir}/target/test-classes
+ **/Test*.java
**/*Test.java
+ **/*Tests.java
+ **/*TestCase.java
**/TestBean.java
+
+ **/AllTests.java
diff --git a/src/test/java/com/yahoo/platform/yui/compressor/CompressionTest.java b/src/test/java/com/yahoo/platform/yui/compressor/CompressionTest.java
new file mode 100644
index 0000000..8920112
--- /dev/null
+++ b/src/test/java/com/yahoo/platform/yui/compressor/CompressionTest.java
@@ -0,0 +1,45 @@
+package com.yahoo.platform.yui.compressor;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import junit.framework.TestCase;
+
+public class CompressionTest extends TestCase {
+ private String javascript(String source, boolean munge) throws Exception {
+ StringWriter output = new StringWriter();
+ new JavaScriptCompressor(new StringReader(source), null)
+ .compress(output, null, -1, munge, false, false, false);
+ return output.toString();
+ }
+
+ public void testJavascriptCompressionMungesLocalNames() throws Exception {
+ String source = "/* remove me */ function sum(first, second) { var result = first + second; return result; } sum(19, 23);";
+ String compressed = javascript(source, true);
+ assertTrue(compressed.length() < source.length());
+ assertFalse(compressed.contains("remove me"));
+ assertTrue(compressed, compressed.matches(
+ "function sum\\(([a-z]),([a-z])\\)\\{var ([a-z])=\\1\\+\\2;return \\3\\}sum\\(19,23\\);"));
+ }
+
+ public void testJavascriptPreservesRegexAndStringLiterals() throws Exception {
+ String source = "var url = 'https://example.com/a'; var pattern = /https?:\\/\\//; pattern.test(url) ? url : 'bad';";
+ assertEquals("var url=\"https://example.com/a\";var pattern=/https?:\\/\\//;pattern.test(url)?url:\"bad\";", javascript(source, false));
+ }
+
+ private String css(String source) throws Exception {
+ StringWriter output = new StringWriter();
+ new CssCompressor(new StringReader(source)).compress(output, -1);
+ return output.toString();
+ }
+
+ public void testCssCompressionRemovesCommentsAndWhitespace() throws Exception {
+ assertEquals("body{margin:0;padding:0;color:#fff}",
+ css("/* remove me */ body { margin: 0px; padding: 0px; color: #ffffff; }"));
+ }
+
+ public void testCssPreservesQuotedContentAndDataUrl() throws Exception {
+ String compressed = css(".icon { background: url(data:image/png;base64,AAAA); } .label:after { content: \"a b\"; }");
+ assertTrue(compressed.contains("url(data:image/png;base64,AAAA)"));
+ assertTrue(compressed.contains("\"a b\""));
+ }
+}