mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-21756 icu4j: port UnicodeKnownIssues.java from CLDR
- port of CLDR-14588 - use a fake Consumer<String> - currently logs after each test class, not ideal but better - Formerly ICU-12589 but that is not as related - add unit test
This commit is contained in:
parent
f5cc0c43d6
commit
7bc2009f7f
3 changed files with 313 additions and 36 deletions
|
@ -0,0 +1,143 @@
|
|||
// © 2021 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: https://www.unicode.org/copyright.html
|
||||
|
||||
package com.ibm.icu.dev.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/**
|
||||
* Test for {@link UnicodeKnownIssues}
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class TestUnicodeKnownIssues {
|
||||
@Test
|
||||
public void TestBasic() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "ICU-21756", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Three", 3, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/ICU-21756"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestNotCurtailed() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "ICU-21756", "Something is working!");
|
||||
uki.logKnownIssue("d/e/f", "ICU-21756", "Something is working!");
|
||||
uki.logKnownIssue("g/h/i", "ICU-21756", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of 5", 5, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/ICU-21756"));
|
||||
// Not curtailed: test shows up in a/b/c, d/e/f, and g/h/i
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
assertTrue(l.get(3) + "#3 says d/e/f", l.get(3).contains("d/e/f"));
|
||||
assertTrue(l.get(4) + "#4 says g/h/i", l.get(4).contains("g/h/i"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCurtailed() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(false);
|
||||
uki.logKnownIssue("a/b/c", "ICU-21756", "Something is working!");
|
||||
uki.logKnownIssue("d/e/f", "ICU-21756", "Something is working!");
|
||||
uki.logKnownIssue("g/h/i", "ICU-21756", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count", 4, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/ICU-21756"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
// Curtailed: the next line has "... and 2 more"
|
||||
assertTrue(l.get(3) + "#3 has 'and 2 more'", l.get(3).contains("and 2 more"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestBare() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "21756", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Three", 3, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/ICU-21756"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestUnknown() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "zzz", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Three", 3, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has unknown ticket", l.get(1).contains("Unknown Ticket"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCldrLink() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "CLDR-9787", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Three", 3, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/CLDR-9787"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCldrBug() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
uki.logKnownIssue("a/b/c", "cldrbug:9787", "Something is working!");
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Three", 3, l.size());
|
||||
assertTrue(l.get(0) + "#0 says Known Issues", l.get(0).contains("Known Issues"));
|
||||
assertTrue(l.get(1) + "#1 has atlassian URL", l.get(1).contains("browse/CLDR-9787"));
|
||||
assertTrue(l.get(2) + "#2 says a/b/c", l.get(2).contains("a/b/c"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void TestNoProblem() {
|
||||
UnicodeKnownIssues uki = new UnicodeKnownIssues(true);
|
||||
List<String> l = printToList(uki);
|
||||
assertNotNull("no list", l);
|
||||
assertEquals("message count Of Zero", 0, l.size());
|
||||
}
|
||||
|
||||
List<String> printToList(UnicodeKnownIssues uki) {
|
||||
// TODO: for JDK 1.8
|
||||
// final List<String> l = new LinkedList<>();
|
||||
// uki.printKnownIssues(s -> l.add(s));
|
||||
|
||||
// TODO: Pre JDK 1.8 below
|
||||
MyConsumer m = new MyConsumer();
|
||||
uki.printKnownIssues(m);
|
||||
return m.l;
|
||||
}
|
||||
|
||||
// TODO: remove for JDK 1.8
|
||||
static final class MyConsumer implements UnicodeKnownIssues.Consumer<String> {
|
||||
final List<String> l = new LinkedList<>();
|
||||
@Override
|
||||
public void accept(String t) {
|
||||
l.add(t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import java.util.Random;
|
|||
import java.util.TreeMap;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
||||
|
@ -112,6 +113,17 @@ abstract public class TestFmwk extends AbstractTestLog {
|
|||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public final static void testClassTeardown() {
|
||||
getParams().knownIssues.printKnownIssues(new UnicodeKnownIssues.Consumer<String>() {
|
||||
// TODO: make this a Lambda once JDK 1.8 ships
|
||||
public void accept(String t) {
|
||||
System.out.println(t);
|
||||
}
|
||||
});
|
||||
getParams().knownIssues.reset();
|
||||
}
|
||||
|
||||
private static TestParams getParams() {
|
||||
//return paramsReference.get();
|
||||
return testParams;
|
||||
|
@ -170,10 +182,6 @@ abstract public class TestFmwk extends AbstractTestLog {
|
|||
|
||||
}
|
||||
|
||||
static final String ICU_TRAC_URL = "http://bugs.icu-project.org/trac/ticket/";
|
||||
static final String CLDR_TRAC_URL = "http://unicode.org/cldr/trac/ticket/";
|
||||
static final String CLDR_TICKET_PREFIX = "cldrbug:";
|
||||
|
||||
/**
|
||||
* Log the known issue.
|
||||
* This method returns true unless -prop:logKnownIssue=no is specified
|
||||
|
@ -189,41 +197,12 @@ abstract public class TestFmwk extends AbstractTestLog {
|
|||
if (!getBooleanProperty("logKnownIssue", true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This method currently does not do very much.
|
||||
// See http://bugs.icu-project.org/trac/ticket/12589
|
||||
|
||||
StringBuffer descBuf = new StringBuffer();
|
||||
// TODO(junit) : what to do about this?
|
||||
final String path = "";
|
||||
//getParams().stack.appendPath(descBuf);
|
||||
if (comment != null && comment.length() > 0) {
|
||||
descBuf.append(" (" + comment + ")");
|
||||
}
|
||||
String description = descBuf.toString();
|
||||
|
||||
String ticketLink = "Unknown Ticket";
|
||||
if (ticket != null && ticket.length() > 0) {
|
||||
boolean isCldr = false;
|
||||
ticket = ticket.toLowerCase(Locale.ENGLISH);
|
||||
if (ticket.startsWith(CLDR_TICKET_PREFIX)) {
|
||||
isCldr = true;
|
||||
ticket = ticket.substring(CLDR_TICKET_PREFIX.length());
|
||||
}
|
||||
ticketLink = (isCldr ? CLDR_TRAC_URL : ICU_TRAC_URL) + ticket;
|
||||
}
|
||||
|
||||
if (getParams().knownIssues == null) {
|
||||
getParams().knownIssues = new TreeMap<String, List<String>>();
|
||||
}
|
||||
List<String> lines = getParams().knownIssues.get(ticketLink);
|
||||
if (lines == null) {
|
||||
lines = new ArrayList<String>();
|
||||
getParams().knownIssues.put(ticketLink, lines);
|
||||
}
|
||||
if (!lines.contains(description)) {
|
||||
lines.add(description);
|
||||
}
|
||||
|
||||
getParams().knownIssues.logKnownIssue(path, ticket, comment);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -365,7 +344,7 @@ abstract public class TestFmwk extends AbstractTestLog {
|
|||
private SecurityManager testSecurityManager;
|
||||
private SecurityManager originalSecurityManager;
|
||||
|
||||
private Map<String, List<String>> knownIssues;
|
||||
private UnicodeKnownIssues knownIssues = null;
|
||||
|
||||
private Properties props;
|
||||
|
||||
|
@ -377,6 +356,7 @@ abstract public class TestFmwk extends AbstractTestLog {
|
|||
TestParams params = new TestParams();
|
||||
Properties props = System.getProperties();
|
||||
params.parseProperties(props);
|
||||
params.knownIssues = new UnicodeKnownIssues(params.getBooleanProperty("allKnownIssues", false));
|
||||
return params;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
// © 2021 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: https://www.unicode.org/copyright.html
|
||||
|
||||
package com.ibm.icu.dev.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* “Known issues” manager.
|
||||
* Intended to be shared between ICU, CLDR, &c.
|
||||
* Test frameworks can create an instance of this to manage known issues
|
||||
*/
|
||||
public class UnicodeKnownIssues {
|
||||
/**
|
||||
* From Java 1.8
|
||||
*/
|
||||
public interface Consumer<T> { void accept(T t); }
|
||||
|
||||
private Map<String, List<String>> knownIssues = new TreeMap<>();
|
||||
/**
|
||||
* Max number of lines to show by default (including the "more")
|
||||
* unless -allKnownIssues is given. Must be at least 2.
|
||||
*/
|
||||
public static final int KNOWN_ISSUES_CURTAILMENT = 2;
|
||||
|
||||
/**
|
||||
* true if all issues should be shown, false if they should
|
||||
* be curtailed.
|
||||
*/
|
||||
private boolean allKnownIssues;
|
||||
|
||||
/**
|
||||
* Construct a known issue manager
|
||||
* @param allKnownIssues true if all known issues should be printed,
|
||||
* not curtailed
|
||||
*/
|
||||
public UnicodeKnownIssues(boolean allKnownIssues) {
|
||||
this.allKnownIssues = allKnownIssues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base URL for browsing Unicode JIRA
|
||||
*/
|
||||
public static final String UNICODE_JIRA_BROWSE = "https://unicode-org.atlassian.net/browse/";
|
||||
|
||||
static final Pattern ICU_TICKET_PATTERN = Pattern.compile(
|
||||
"(?i)(?:icu-)?(\\d+)"
|
||||
);
|
||||
static final Pattern CLDR_TICKET_PATTERN = Pattern.compile(
|
||||
"(?i)cldr(?:bug:)?(?:-)?(\\d+)"
|
||||
);
|
||||
|
||||
/**
|
||||
* Match all linkable ticket patterns
|
||||
* @see {org.unicode.cldr.util.CLDRURLS#CLDR_TICKET_BROWSE}
|
||||
*/
|
||||
static final Pattern UNICODE_JIRA_PATTERN = Pattern.compile(
|
||||
"(CLDR|ICU)-(\\d+)"
|
||||
);
|
||||
|
||||
/**
|
||||
* Log the known issue.
|
||||
* Call this from the test framework when logKnownIssue() is called.
|
||||
*
|
||||
* @param path Path to the error, will be returned in the
|
||||
* known issue list
|
||||
* @param ticket A ticket number string. For an ICU ticket, use "ICU-10245".
|
||||
* For a CLDR ticket, use "CLDR-12345".
|
||||
* For compatibility, "1234" -> ICU-1234 and "cldrbug:456" -> CLDR-456
|
||||
* @param comment Additional comment, or null
|
||||
*
|
||||
*/
|
||||
public void logKnownIssue(String path, String ticket, String comment) {
|
||||
|
||||
StringBuilder descBuf = new StringBuilder(path);
|
||||
|
||||
if (comment != null && comment.length() > 0) {
|
||||
descBuf.append(" (" + comment + ")");
|
||||
}
|
||||
String description = descBuf.toString();
|
||||
|
||||
String ticketLink = "Unknown Ticket";
|
||||
if (ticket != null && ticket.length() > 0) {
|
||||
Matcher matcher = ICU_TICKET_PATTERN.matcher(ticket);
|
||||
if (matcher.matches()) {
|
||||
ticketLink = "ICU-" + matcher.group(1);
|
||||
} else {
|
||||
matcher = CLDR_TICKET_PATTERN.matcher(ticket);
|
||||
if (matcher.matches()) {
|
||||
ticketLink = "CLDR-" + matcher.group(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> lines = knownIssues.get(ticketLink);
|
||||
if (lines == null) {
|
||||
lines = new ArrayList<>();
|
||||
knownIssues.put(ticketLink, lines);
|
||||
}
|
||||
if (!lines.contains(description)) {
|
||||
lines.add(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out all known issues to the logFn.
|
||||
* Usage: printKnownIssues(System.out::println)
|
||||
* @param logFn consumer for Strings (e.g. System.out::println)
|
||||
* @return true if (!allKnownIssues) and we had to curtail
|
||||
*/
|
||||
public boolean printKnownIssues(Consumer<String> logFn) {
|
||||
boolean didCurtail = false;
|
||||
if (knownIssues.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
logFn.accept("\n " + knownIssues.size() + " Known Issues:");
|
||||
for (Entry<String, List<String>> entry : knownIssues.entrySet()) {
|
||||
String ticketLink = entry.getKey();
|
||||
if (UNICODE_JIRA_PATTERN.matcher(ticketLink) != null) {
|
||||
logFn.accept(ticketLink + " <" + UNICODE_JIRA_BROWSE + ticketLink + ">");
|
||||
} else {
|
||||
// Unknown or something else
|
||||
logFn.accept("<" + ticketLink + ">");
|
||||
}
|
||||
List<String> entries = entry.getValue();
|
||||
int issuesToShow = entries.size();
|
||||
if (!allKnownIssues && issuesToShow > KNOWN_ISSUES_CURTAILMENT) {
|
||||
issuesToShow = (KNOWN_ISSUES_CURTAILMENT - 1);
|
||||
}
|
||||
for (int i=0; i<issuesToShow; i++) {
|
||||
logFn.accept(" - " + entries.get(i));
|
||||
}
|
||||
if (entries.size() > issuesToShow) {
|
||||
didCurtail = true;
|
||||
logFn.accept(" ... and " +
|
||||
(entries.size() - issuesToShow) + " more");
|
||||
}
|
||||
}
|
||||
return didCurtail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the known issues
|
||||
*/
|
||||
public void reset() {
|
||||
knownIssues.clear();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue