blob: e843146e9d5dd00a39fc537c38abffe81f7b1a0c [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.emultest.java.lang;
import com.google.gwt.junit.client.GWTTestCase;
/**
* Tests for java.lang.Character.
*/
public class CharacterTest extends GWTTestCase {
private static class CharSequenceAdapter implements CharSequence {
private char[] charArray;
private int start;
private int end;
public CharSequenceAdapter(char[] charArray) {
this(charArray, 0, charArray.length);
}
public CharSequenceAdapter(char[] charArray, int start, int end) {
this.charArray = charArray;
this.start = start;
this.end = end;
}
@Override
public char charAt(int index) {
return charArray[index + start];
}
@Override
public int length() {
return end - start;
}
@Override
public java.lang.CharSequence subSequence(int start, int end) {
return new CharSequenceAdapter(charArray, this.start + start,
this.start + end);
}
}
/**
* Helper class which applies some arbitrary char mutation function
* to a string and returns it.
*/
public abstract class Changer {
String original;
public Changer(String o) {
original = o;
}
public abstract char change(char c);
public String changed() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < original.length(); i++) {
buf.append(change(original.charAt(i)));
}
return buf.toString();
}
}
/**
* Helper class which collects the set of characters which pass some
* arbitrary boolean function.
*/
public abstract class Judge {
String original;
public Judge(String o) {
original = o;
}
public String allPass() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < original.length(); i++) {
if (pass(original.charAt(i))) {
buf.append(original.charAt(i));
}
}
return buf.toString();
}
public abstract boolean pass(char c);
}
class LowerCaseJudge extends Judge {
public LowerCaseJudge(String s) {
super(s);
}
@Override
public boolean pass(char c) {
return Character.isLowerCase(c);
}
}
class UpperCaseJudge extends Judge {
public UpperCaseJudge(String s) {
super(s);
}
@Override
public boolean pass(char c) {
return Character.isUpperCase(c);
}
}
public static String allChars;
public static final int NUM_CHARS_HANDLED = 127;
static {
StringBuffer b = new StringBuffer();
for (char c = 0; c < NUM_CHARS_HANDLED; c++) {
b.append(c);
}
allChars = b.toString();
}
Judge digitJudge = new Judge(allChars) {
@Override
public boolean pass(char c) {
return Character.isDigit(c);
}
};
Judge letterJudge = new Judge(allChars) {
@Override
public boolean pass(char c) {
return Character.isLetter(c);
}
};
Judge letterOrDigitJudge = new Judge(allChars) {
@Override
public boolean pass(char c) {
return Character.isLetterOrDigit(c);
}
};
Changer lowerCaseChanger = new Changer(allChars) {
@Override
public char change(char c) {
return Character.toLowerCase(c);
}
};
Judge lowerCaseJudge = new LowerCaseJudge(allChars);
Judge spaceJudge = new Judge(allChars) {
@Override
@SuppressWarnings("deprecation") // Character.isSpace()
public boolean pass(char c) {
return Character.isSpace(c); // suppress deprecation
}
};
Changer upperCaseChanger = new Changer(allChars) {
@Override
public char change(char c) {
return Character.toUpperCase(c);
}
};
Judge upperCaseJudge = new UpperCaseJudge(allChars);
@Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
}
public void testCharValue() {
assertEquals((char) 32, new Character((char) 32).charValue());
}
public void testCodePoint() {
assertEquals(1, Character.charCount(65));
assertEquals(2, Character.charCount(Character.MIN_SUPPLEMENTARY_CODE_POINT));
char[] testPlain = new char[] { 'C', 'A', 'T' };
char[] testUnicode = new char[] { 'C', '\uD801', '\uDF00', 'T' };
CharSequence plainSequence = new CharSequenceAdapter(testPlain);
CharSequence unicodeSequence = new CharSequenceAdapter(testUnicode);
assertEquals(65, Character.codePointAt(testPlain, 1));
assertEquals(65, Character.codePointAt(plainSequence, 1));
assertEquals("codePointAt fails on surrogate pair", 67328,
Character.codePointAt(testUnicode, 1));
assertEquals("codePointAt fails on surrogate pair", 67328,
Character.codePointAt(unicodeSequence, 1));
assertEquals("codePointAt fails on first char of surrogate pair", 0xD801,
Character.codePointAt(testUnicode, 1, 2));
assertEquals(65, Character.codePointBefore(testPlain, 2));
assertEquals(65, Character.codePointBefore(plainSequence, 2));
assertEquals("codePointBefore fails on surrogate pair", 67328,
Character.codePointBefore(testUnicode, 3));
assertEquals("codePointBefore fails on surrogate pair", 67328,
Character.codePointBefore(unicodeSequence, 3));
assertEquals("codePointBefore fails on second char of surrogate pair",
0xDF00, Character.codePointBefore(testUnicode, 3, 2));
assertEquals("codePointCount(plain): ", 3,
Character.codePointCount(testPlain, 0, 3));
assertEquals("codePointCount(plain): ", 3,
Character.codePointCount(plainSequence, 0, 3));
assertEquals("codePointCount(unicode): ", 3,
Character.codePointCount(testUnicode, 0, 4));
assertEquals("codePointCount(unicode): ", 3,
Character.codePointCount(unicodeSequence, 0, 4));
assertEquals(1, Character.codePointCount(testPlain, 1, 1));
assertEquals(1, Character.codePointCount(plainSequence, 1, 2));
assertEquals(1, Character.codePointCount(testUnicode, 1, 2));
assertEquals(1, Character.codePointCount(unicodeSequence, 1, 3));
assertEquals(2, Character.codePointCount(testUnicode, 2, 2));
assertEquals(2, Character.codePointCount(unicodeSequence, 2, 4));
assertEquals(1, Character.offsetByCodePoints(testUnicode, 0, 4, 0, 1));
assertEquals(1, Character.offsetByCodePoints(unicodeSequence, 0, 1));
assertEquals("offsetByCodePoints(1,1): ", 3,
Character.offsetByCodePoints(testUnicode, 0, 4, 1, 1));
assertEquals("offsetByCodePoints(1,1): ", 3,
Character.offsetByCodePoints(unicodeSequence, 1, 1));
assertEquals("offsetByCodePoints(2,1): ", 3,
Character.offsetByCodePoints(testUnicode, 0, 4, 2, 1));
assertEquals("offsetByCodePoints(2,1): ", 3,
Character.offsetByCodePoints(unicodeSequence, 2, 1));
assertEquals(4, Character.offsetByCodePoints(testUnicode, 0, 4, 3, 1));
assertEquals(4, Character.offsetByCodePoints(unicodeSequence, 3, 1));
assertEquals(1, Character.offsetByCodePoints(testUnicode, 0, 4, 2, -1));
assertEquals(1, Character.offsetByCodePoints(unicodeSequence, 2, -1));
assertEquals(1, Character.offsetByCodePoints(testUnicode, 0, 4, 3, -1));
assertEquals(1, Character.offsetByCodePoints(unicodeSequence, 3, -1));
assertEquals("offsetByCodePoints(4.-1): ", 3,
Character.offsetByCodePoints(testUnicode, 0, 4, 4, -1));
assertEquals("offsetByCodePoints(4.-1): ", 3,
Character.offsetByCodePoints(unicodeSequence, 4, -1));
assertEquals(0, Character.offsetByCodePoints(testUnicode, 0, 4, 3, -2));
assertEquals(0, Character.offsetByCodePoints(unicodeSequence, 3, -2));
char[] nonBmpChar = new char[] { '\uD800', '\uDF46' };
assertEquals(0x10346, Character.codePointAt(nonBmpChar, 0));
assertEquals(1, Character.codePointCount(nonBmpChar, 0, 2));
}
public void testCompare() {
assertTrue(Character.compare('A', 'B') < 0);
assertTrue(Character.compare('B', 'A') > 0);
assertEquals(0, Character.compare('C', 'C'));
assertTrue(Character.compare('\uA001', '\uA000') > 0);
}
public void testCompareTo() {
assertTrue(Character.valueOf('A').compareTo('B') < 0);
assertTrue(Character.valueOf('B').compareTo('A') > 0);
assertTrue(Character.valueOf('C').compareTo('C') == 0);
assertTrue(Character.valueOf('\uA001').compareTo('\uA000') > 0);
}
public void testConstructor() {
assertEquals(new Character((char) 32), new Character(' '));
}
public void testDigit() {
assertEquals("wrong number of digits", 10, digitJudge.allPass().length());
}
public void testSurrogates() {
assertFalse(Character.isHighSurrogate('\uDF46'));
assertTrue(Character.isLowSurrogate('\uDF46'));
assertTrue(Character.isHighSurrogate('\uD800'));
assertFalse(Character.isLowSurrogate('\uD800'));
assertFalse(Character.isHighSurrogate('X'));
assertFalse(Character.isLowSurrogate('X'));
assertTrue(Character.isSurrogatePair('\uD800', '\uDF46'));
assertFalse(Character.isSurrogatePair('\uDF46', '\uD800'));
assertFalse(Character.isSurrogatePair('A', '\uDF46'));
assertFalse(Character.isSurrogatePair('\uD800', 'A'));
char[] chars = Character.toChars(0x10346);
assertEquals(0xD800, chars[0]);
assertEquals(0xDF46, chars[1]);
assertEquals(2, Character.toChars(67328, chars, 0));
assertEquals(0xD801, chars[0]);
assertEquals(0xDF00, chars[1]);
assertEquals(1, Character.toChars(65, chars, 0));
assertEquals('A', chars[0]);
assertTrue(Character.isSupplementaryCodePoint(0x10346));
assertFalse(Character.isSupplementaryCodePoint(65));
assertTrue(Character.isValidCodePoint(0x10346));
assertTrue(Character.isValidCodePoint(65));
assertFalse(Character.isValidCodePoint(0x1FFFFFFF));
assertEquals(0x10346, Character.toCodePoint('\uD800', '\uDF46'));
}
public void testLetter() {
assertEquals("wrong number of letters", 52, letterJudge.allPass().length());
}
public void testLetterOrDigit() {
assertEquals("wrong number of letters", 62,
letterOrDigitJudge.allPass().length());
}
public void testLowerCase() {
assertEquals("wrong number of lowercase letters", 26,
lowerCaseJudge.allPass().length());
assertEquals("wrong number of lowercase letters after toLowerCase", 52,
new LowerCaseJudge(lowerCaseChanger.changed()).allPass().length());
}
public void testSpace() {
assertEquals("wrong number of spaces", 5, spaceJudge.allPass().length());
}
public void testToFromDigit() {
for (int i = 0; i < 16; i++) {
assertEquals(i, Character.digit(Character.forDigit(i, 16), 16));
}
assertEquals(1, Character.digit('1', 10));
assertEquals('9', Character.forDigit(9, 10));
assertEquals(-1, Character.digit('7', 6));
assertEquals(-1, Character.digit('8', 8));
assertEquals(-1, Character.digit('A', 10));
}
@SuppressWarnings("deprecation")
public void testIsSpace() {
assertFalse(Character.isSpace('a'));
assertFalse(Character.isSpace('_'));
assertTrue(Character.isSpace(' '));
assertTrue(Character.isSpace('\n'));
}
public void testIsWhitepace() {
char[] separators = {
'\u0020', // SPACE.
'\u1680', // OGHAM SPACE MARK.
'\u2000', // EN QUAD.
'\u2001', // EM QUAD.
'\u2002', // EN SPACE.
'\u2003', // EM SPACE.
'\u2004', // THREE-PER-EM SPACE.
'\u2005', // FOUR-PER-EM SPACE.
'\u2006', // SIX-PER-EM SPACE.
'\u2008', // PUNCTUATION SPACE.
'\u2009', // THIN SPACE.
'\u200A', // HAIR SPACE.
'\u2028', // LINE SEPARATOR.
'\u2029', // PARAGRAPH SEPARATOR.
'\u205F', // MEDIUM MATHEMATICAL SPACE.
'\u3000' // IDEOGRAPHIC SPACE.
};
char[] nonBreakingSpaceSeparators = {
'\u00A0', // NO-BREAK SPACE.
'\u2007', // FIGURE SPACE.
'\u202F' // NARROW NO-BREAK SPACE.
};
char[] specialCases = {
'\t', // HORIZONTAL TABULATION.
'\n', // LINE FEED.
'\u000B', // VERTICAL TABULATION.
'\f', // FORM FEED.
'\r', // CARRIAGE RETURN.
'\u001C', // FILE SEPARATOR.
'\u001D', // GROUP SEPARATOR.
'\u001E', // RECORD SEPARATOR.
'\u001F' // UNIT SEPARATOR.
};
char[] typicalCounterExamples = {
'a', // LATIN SMALL LETTER A.
'B', // LATIN CAPITAL LETTER B.
'_', // LOW LINE.
'\u2500' // BOX DRAWINGS LIGHT HORIZONTAL.
};
int[] supplementaryCounterExamples = {
0x2070E, // UNICODE HAN CHARACTER 'to castrate a fowl, a capon'.
0x20731, // UNICODE HAN CHARACTER 'to peel, pare'.
0x29D98, // UNICODE HAN CHARACTER 'a general name for perch, etc.'.
};
// Must match unicode space separator characters.
for (char c : separators) {
assertTrue(Character.isWhitespace(c));
assertTrue(Character.isWhitespace((int) c));
}
// But NOT the non-breaking spaces.
for (char c : nonBreakingSpaceSeparators) {
assertFalse(Character.isWhitespace(c));
assertFalse(Character.isWhitespace((int) c));
}
// The ASCII legacy cases.
for (char c : specialCases) {
assertTrue(Character.isWhitespace(c));
assertTrue(Character.isWhitespace((int) c));
}
// Behave appropriately on other characters, like the alphabet.
for (char c : typicalCounterExamples) {
assertFalse(Character.isWhitespace(c));
assertFalse(Character.isWhitespace((int) c));
}
// Support for non-UCS-2 characters.
for (int c : supplementaryCounterExamples) {
assertFalse(Character.isWhitespace(c));
}
}
public void testToString() {
assertEquals(" ", new Character((char) 32).toString());
}
public void testUpperCase() {
assertEquals("wrong number of uppercase letters", 26,
upperCaseJudge.allPass().length());
assertEquals("wrong number of uppercase letters after toUpperCase", 52,
new UpperCaseJudge(upperCaseChanger.changed()).allPass().length());
}
public void testValueOf() {
assertEquals('A', Character.valueOf('A').charValue());
}
}