summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2010-04-22 13:38:42 -0700
committerElliott Hughes <enh@google.com>2010-04-22 14:00:53 -0700
commita7d4139bed693bf6037bf5f7f49a24b077102adc (patch)
treedb9d78c4a6cc9478a88996acd08f7b19be0cba48
parent5779f05dd67ea322017c4ceb45270f5c6969d6b5 (diff)
downloadlibcore-a7d4139bed693bf6037bf5f7f49a24b077102adc.zip
libcore-a7d4139bed693bf6037bf5f7f49a24b077102adc.tar.gz
libcore-a7d4139bed693bf6037bf5f7f49a24b077102adc.tar.bz2
java.text.RuleBasedCollator fixes.
Add expectations for broken harmony tests, add our own equivalent (but correct) tets, and fix the bug turned up by the correct tests: the icu4jni RuleBasedCollator was using toString to convert a CharacterIterator to a String, resulting in iteration over the result of Object.toString (the class name and identity hash code) rather than the characters of interest. Also shut javac up about non-ASCII characters in Locale.java. Bug: 2608742 Bug: 2608750 Change-Id: I2171789058c8116eacd7e5815bd483f0bc07c69b
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java13
-rw-r--r--luni/src/main/java/java/util/Locale.java4
-rw-r--r--luni/src/test/java/java/text/CollatorTest.java61
-rw-r--r--text/src/main/java/java/text/RuleBasedCollator.java11
-rw-r--r--tools/runner/expectations/brokentests.txt17
5 files changed, 97 insertions, 9 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
index a87c978..3135daa 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
@@ -516,8 +516,17 @@ public final class RuleBasedCollator extends Collator {
return result;
}
- public CollationElementIterator getCollationElementIterator(CharacterIterator source) {
- return getCollationElementIterator(source.toString());
+ public CollationElementIterator getCollationElementIterator(CharacterIterator it) {
+ // We only implement the String-based API, so build a string from the iterator.
+ return getCollationElementIterator(characterIteratorToString(it));
+ }
+
+ private String characterIteratorToString(CharacterIterator it) {
+ StringBuilder result = new StringBuilder();
+ for (char ch = it.current(); ch != CharacterIterator.DONE; ch = it.next()) {
+ result.append(ch);
+ }
+ return result.toString();
}
/**
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 7d03eac..c6535c1 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -392,8 +392,8 @@ public final class Locale implements Cloneable, Serializable {
* to {@code locale}. The exact output form depends on whether this locale
* corresponds to a specific language, country and variant, such as:
* {@code English}, {@code English (United States)}, {@code English (United
- * States,Computer)}, {@code anglais (États-Unis)}, {@code anglais
- * (États-Unis,informatique)}.
+ * States,Computer)}, {@code anglais (&#x00c9;tats-Unis)}, {@code anglais
+ * (&#x00c9;tats-Unis,informatique)}.
*/
public String getDisplayName(Locale locale) {
int count = 0;
diff --git a/luni/src/test/java/java/text/CollatorTest.java b/luni/src/test/java/java/text/CollatorTest.java
index 48c0eb1..5cded0a 100644
--- a/luni/src/test/java/java/text/CollatorTest.java
+++ b/luni/src/test/java/java/text/CollatorTest.java
@@ -82,4 +82,65 @@ public class CollatorTest extends junit.framework.TestCase {
assertTrue("Error: \u00e0\u0325 should equal to a\u0325\u0300 with decomposition",
myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
}
+
+ public void testEqualsObject() throws ParseException {
+ String rule = "< a < b < c < d < e";
+ RuleBasedCollator coll = new RuleBasedCollator(rule);
+
+ assertEquals(Collator.TERTIARY, coll.getStrength());
+ // This is a harmony test, but it assumes that RuleBasedCollators default to
+ // NO_DECOMPOSITION, which isn't true on Android.
+ // assertEquals(Collator.NO_DECOMPOSITION, coll.getDecomposition());
+ RuleBasedCollator other = new RuleBasedCollator(rule);
+ assertTrue(coll.equals(other));
+
+ coll.setStrength(Collator.PRIMARY);
+ assertFalse(coll.equals(other));
+
+ coll.setStrength(Collator.TERTIARY);
+ coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+ other.setDecomposition(Collator.NO_DECOMPOSITION); // See comment above.
+ assertFalse(coll.equals(other));
+ }
+
+ public void test_Harmony_1352() throws Exception {
+ // Regression test for HARMONY-1352, that doesn't get run in the harmony test suite because
+ // of an earlier failure.
+ try {
+ new RuleBasedCollator("< a< b< c< d").getCollationElementIterator((CharacterIterator) null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ private void assertCollationElementIterator(CollationElementIterator it, Integer... offsets) {
+ for (int offset : offsets) {
+ assertEquals(offset, it.getOffset());
+ it.next();
+ }
+ assertEquals(CollationElementIterator.NULLORDER, it.next());
+ }
+
+ private void assertGetCollationElementIteratorString(Locale l, String s, Integer... offsets) {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
+ assertCollationElementIterator(coll.getCollationElementIterator(s), offsets);
+ }
+
+ private void assertGetCollationElementIteratorCharacterIterator(Locale l, String s, Integer... offsets) {
+ RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
+ CharacterIterator it = new StringCharacterIterator(s);
+ assertCollationElementIterator(coll.getCollationElementIterator(it), offsets);
+ }
+
+ public void testGetCollationElementIteratorString() throws Exception {
+ assertGetCollationElementIteratorString(new Locale("es", "", "TRADITIONAL"), "cha", 0, 2, 3);
+ assertGetCollationElementIteratorString(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
+ assertGetCollationElementIteratorString(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
+ }
+
+ public void testGetCollationElementIteratorCharacterIterator() throws Exception {
+ assertGetCollationElementIteratorCharacterIterator(new Locale("es", "", "TRADITIONAL"), "cha", 0, 2, 3);
+ assertGetCollationElementIteratorCharacterIterator(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
+ assertGetCollationElementIteratorCharacterIterator(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
+ }
}
diff --git a/text/src/main/java/java/text/RuleBasedCollator.java b/text/src/main/java/java/text/RuleBasedCollator.java
index 77492b5..0955f89 100644
--- a/text/src/main/java/java/text/RuleBasedCollator.java
+++ b/text/src/main/java/java/text/RuleBasedCollator.java
@@ -269,15 +269,14 @@ public class RuleBasedCollator extends Collator {
* the result of a former {@link #getRules()} call.
* <p>
* Note that the {@code rules} are actually interpreted as a delta to the
- * standard Unicode Collation Algorithm (UCA). Hence, an empty {@code rules}
- * string results in the default UCA rules being applied. This differs
+ * standard Unicode Collation Algorithm (UCA). This differs
* slightly from other implementations which work with full {@code rules}
* specifications and may result in different behavior.
*
* @param rules
* the collation rules.
* @throws NullPointerException
- * if {@code rules} is {@code null}.
+ * if {@code rules == null}.
* @throws ParseException
* if {@code rules} contains rules with invalid collation rule
* syntax.
@@ -286,6 +285,9 @@ public class RuleBasedCollator extends Collator {
if (rules == null) {
throw new NullPointerException();
}
+ if (rules.isEmpty()) {
+ throw new ParseException("empty rules", 0);
+ }
try {
this.icuColl = new com.ibm.icu4jni.text.RuleBasedCollator(rules);
this.icuColl.setDecomposition(com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION);
@@ -310,8 +312,7 @@ public class RuleBasedCollator extends Collator {
* the source character iterator.
* @return a {@code CollationElementIterator} for {@code source}.
*/
- public CollationElementIterator getCollationElementIterator(
- CharacterIterator source) {
+ public CollationElementIterator getCollationElementIterator(CharacterIterator source) {
if (source == null) {
throw new NullPointerException();
}
diff --git a/tools/runner/expectations/brokentests.txt b/tools/runner/expectations/brokentests.txt
index 2d98c23..75624ee 100644
--- a/tools/runner/expectations/brokentests.txt
+++ b/tools/runner/expectations/brokentests.txt
@@ -711,3 +711,20 @@ result EXEC_FAILED
pattern .*GMT-07:00.*
+# These harmony tests are broken. The RI doesn't ship with es__TRADITIONAL, so
+# they have incorrect expectations.
+# http://b/2608750
+
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testGetCollationElementIteratorCharacterIterator
+result EXEC_FAILED
+pattern .*expected:<1> but was:<2>.*
+
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testGetCollationElementIteratorString
+result EXEC_FAILED
+pattern .*expected:<1> but was:<2>.*
+
+# This test fails because on Android, RuleBasedCollators default to
+# CANONICAL_DECOMPOSITION, not NO_DECOMPOSITION.
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testEqualsObject
+result EXEC_FAILED
+pattern .*expected:<0> but was:<1>.*