Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/scripts/verify-test-reports.py
Original file line number Diff line number Diff line change
@@ -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')
18 changes: 5 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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
Expand All @@ -45,10 +33,14 @@ 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
with:
name: surefire-reports-jdk${{ matrix.java }}
path: target/surefire-reports
retention-days: 14
if-no-files-found: error
15 changes: 7 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,21 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<!-- 跳过单元测试 -->
<skip>true</skip>
<skipTests>true</skipTests>
<!-- forkMode 可设置值有 “never”, “once”, “always” 和 “pertest”。 pretest:
每一个测试创建一个新进程,为每个测试创建新的JVM是单独测试的最彻底方式,但也是最慢的,不适合hudson上持续回归。 once:在一个进程中进行所有测试。once为默认设置,在Hudson上持续回归时建议使用默认设置。
always:在一个进程中并行的运行脚本,Junit4.7以上版本才可以使用,surefire的版本要在2.6以上提供这个功能,其中 threadCount:执行时,指定可分配的线程数量。只和参数parallel配合使用有效。默认:5。 -->
<forkMode>once</forkMode>
<argLine>-Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -Dfile.encoding=UTF-8</argLine>
<failIfNoTests>true</failIfNoTests>
<argLine>-Xmx1024m -Dfile.encoding=UTF-8</argLine>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/test-classes</additionalClasspathElement>
</additionalClasspathElements>
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<excludes>
<exclude>**/TestBean.java</exclude>
<!-- Run the JUnit3 test cases directly, not again via their suite. -->
<exclude>**/AllTests.java</exclude>
</excludes>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -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\""));
}
}
Loading