10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/*
20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Copyright (C) 2008 The Guava Authors
30888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * you may not use this file except in compliance with the License.
60888a09821a98ac0680fad765217302858e70fa4Paul Duffin * You may obtain a copy of the License at
70888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
80888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
90888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software
110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * See the License for the specific language governing permissions and
140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * limitations under the License.
150888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
170888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage com.google.common.base;
180888a09821a98ac0680fad765217302858e70fa4Paul Duffin
190888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.BREAKING_WHITESPACE;
200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.WHITESPACE;
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.anyOf;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.forPredicate;
230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.inRange;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.is;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.isNot;
260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.CharMatcher.noneOf;
270888a09821a98ac0680fad765217302858e70fa4Paul Duffin
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.annotations.GwtCompatible;
290888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.Sets;
300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
310888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.AssertionFailedError;
320888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase;
330888a09821a98ac0680fad765217302858e70fa4Paul Duffin
340888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Arrays;
350888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.HashSet;
360888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Random;
370888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Set;
380888a09821a98ac0680fad765217302858e70fa4Paul Duffin
390888a09821a98ac0680fad765217302858e70fa4Paul Duffin/**
400888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unit test for {@link CharMatcher}.
410888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
420888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Kevin Bourrillion
430888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
440888a09821a98ac0680fad765217302858e70fa4Paul Duffin@GwtCompatible(emulated = true)
450888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic class CharMatcherTest extends TestCase {
460888a09821a98ac0680fad765217302858e70fa4Paul Duffin
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final CharMatcher WHATEVER = new CharMatcher() {
480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean matches(char c) {
490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionFailedError(
500888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "You weren't supposed to actually invoke me!");
510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin  };
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin
540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAnyAndNone_logicalOps() throws Exception {
550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // These are testing behavior that's never promised by the API, but since
560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // we're lucky enough that these do pass, it saves us from having to write
570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // more excruciating tests! Hooray!
580888a09821a98ac0680fad765217302858e70fa4Paul Duffin
590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.ANY, CharMatcher.NONE.negate());
600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.NONE, CharMatcher.ANY.negate());
610888a09821a98ac0680fad765217302858e70fa4Paul Duffin
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(WHATEVER, CharMatcher.ANY.and(WHATEVER));
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.ANY, CharMatcher.ANY.or(WHATEVER));
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.NONE, CharMatcher.NONE.and(WHATEVER));
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(WHATEVER, CharMatcher.NONE.or(WHATEVER));
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
680888a09821a98ac0680fad765217302858e70fa4Paul Duffin
690888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // The rest of the behavior of ANY and DEFAULT will be covered in the tests for
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // the text processing methods below.
710888a09821a98ac0680fad765217302858e70fa4Paul Duffin
720888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testWhitespaceBreakingWhitespaceSubset() throws Exception {
730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int c = 0; c <= Character.MAX_VALUE; c++) {
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (BREAKING_WHITESPACE.apply((char) c)) {
750888a09821a98ac0680fad765217302858e70fa4Paul Duffin        assertTrue(Integer.toHexString(c), WHITESPACE.apply((char) c));
760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // The next tests require ICU4J and have, at least for now, been sliced out
810888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // of the open-source view of the tests.
820888a09821a98ac0680fad765217302858e70fa4Paul Duffin
830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // Omitting tests for the rest of the JAVA_* constants as these are defined
840888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // as extremely straightforward pass-throughs to the JDK methods.
850888a09821a98ac0680fad765217302858e70fa4Paul Duffin
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // We're testing the is(), isNot(), anyOf(), noneOf() and inRange() methods
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // below by testing their text-processing methods.
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin
890888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // The organization of this test class is unusual, as it's not done by
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // method, but by overall "scenario". Also, the variety of actual tests we
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // do borders on absurd overkill. Better safe than sorry, though?
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testEmpty() throws Exception {
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(CharMatcher.ANY);
950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(CharMatcher.NONE);
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(is('a'));
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(isNot('a'));
980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(anyOf(""));
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(anyOf("x"));
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(anyOf("xy"));
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(anyOf("CharMatcher"));
1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(noneOf("CharMatcher"));
1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(inRange('n', 'q'));
1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestEmpty(forPredicate(Predicates.equalTo('c')));
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestEmpty(CharMatcher matcher) throws Exception {
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestEmpty(matcher);
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestEmpty(matcher.negate());
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestEmpty(matcher.precomputed());
1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestEmpty(CharMatcher matcher) throws Exception {
1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(""));
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn("", 0));
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      matcher.indexIn("", 1);
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IndexOutOfBoundsException expected) {
1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin      matcher.indexIn("", -1);
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IndexOutOfBoundsException expected) {
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.lastIndexIn(""));
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAnyOf(""));
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAllOf(""));
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesNoneOf(""));
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.removeFrom(""));
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.replaceFrom("", 'z'));
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.replaceFrom("", "ZZ"));
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.trimFrom(""));
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.countIn(""));
1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testNoMatches() {
1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(CharMatcher.NONE, "blah");
1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(is('a'), "bcde");
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(isNot('a'), "aaaa");
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(anyOf(""), "abcd");
1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(anyOf("x"), "abcd");
1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(anyOf("xy"), "abcd");
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(anyOf("CharMatcher"), "zxqy");
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(noneOf("CharMatcher"), "ChMa");
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(inRange('p', 'x'), "mom");
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(forPredicate(Predicates.equalTo('c')), "abe");
1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(inRange('A', 'Z').and(inRange('F', 'K').negate()), "F1a");
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(CharMatcher.DIGIT, "\tAz()");
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(CharMatcher.JAVA_DIGIT, "\tAz()");
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(CharMatcher.DIGIT.and(CharMatcher.ASCII), "\tAz()");
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatches(CharMatcher.SINGLE_WIDTH, "\u05bf\u3000");
1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestNoMatches(CharMatcher matcher, String s) {
1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher, s);
1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher.negate(), s);
1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher.precomputed(), s);
1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher.negate().precomputed(), s);
1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher.precomputed().negate(), s);
1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(forPredicate(matcher), s);
1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher, new StringBuilder(s));
1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testAllMatches() {
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(CharMatcher.ANY, "blah");
1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(isNot('a'), "bcde");
1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(is('a'), "aaaa");
1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(noneOf("CharMatcher"), "zxqy");
1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(anyOf("x"), "xxxx");
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(anyOf("xy"), "xyyx");
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(anyOf("CharMatcher"), "ChMa");
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(inRange('m', 'p'), "mom");
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(forPredicate(Predicates.equalTo('c')), "ccc");
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(CharMatcher.DIGIT, "0123456789\u0ED0\u1B59");
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(CharMatcher.JAVA_DIGIT, "0123456789");
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(CharMatcher.DIGIT.and(CharMatcher.ASCII), "0123456789");
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestAllMatches(CharMatcher.SINGLE_WIDTH, "\t0123ABCdef~\u00A0\u2111");
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestAllMatches(CharMatcher matcher, String s) {
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher, s);
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher.negate(), s);
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher.precomputed(), s);
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher.negate().precomputed(), s);
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatches(matcher.precomputed().negate(), s);
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(forPredicate(matcher), s);
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestAllMatches(matcher, new StringBuilder(s));
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestNoMatches(CharMatcher matcher, CharSequence s) {
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matches(s.charAt(0)));
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s));
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 0));
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 1));
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, s.length()));
1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin      matcher.indexIn(s, s.length() + 1);
2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IndexOutOfBoundsException expected) {
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      matcher.indexIn(s, -1);
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IndexOutOfBoundsException expected) {
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.lastIndexIn(s));
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAnyOf(s));
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAllOf(s));
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesNoneOf(s));
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.toString(), matcher.removeFrom(s));
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.toString(), matcher.replaceFrom(s, 'z'));
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.toString(), matcher.replaceFrom(s, "ZZ"));
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.toString(), matcher.trimFrom(s));
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.countIn(s));
2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestAllMatches(CharMatcher matcher, CharSequence s) {
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matches(s.charAt(0)));
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s));
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s, 0));
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.indexIn(s, 1));
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, s.length()));
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.length() - 1, matcher.lastIndexIn(s));
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAnyOf(s));
2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAllOf(s));
2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesNoneOf(s));
2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.removeFrom(s));
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(Strings.repeat("z", s.length()),
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        matcher.replaceFrom(s, 'z'));
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(Strings.repeat("ZZ", s.length()),
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        matcher.replaceFrom(s, "ZZ"));
2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.trimFrom(s));
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.length(), matcher.countIn(s));
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testGeneral() {
2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(is('a'), 'a', 'b');
2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(isNot('a'), 'b', 'a');
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(anyOf("x"), 'x', 'z');
2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(anyOf("xy"), 'y', 'z');
2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(anyOf("CharMatcher"), 'C', 'z');
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(noneOf("CharMatcher"), 'z', 'C');
2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestGeneral(inRange('p', 'x'), 'q', 'z');
2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestGeneral(CharMatcher matcher, char match, char noMatch) {
2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestOneCharMatch(matcher, "" + match);
2520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestOneCharNoMatch(matcher, "" + noMatch);
2530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestMatchThenNoMatch(matcher, "" + match + noMatch);
2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestNoMatchThenMatch(matcher, "" + noMatch + match);
2550888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestOneCharMatch(CharMatcher matcher, String s) {
2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharMatch(matcher, s);
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharNoMatch(matcher.negate(), s);
2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharMatch(matcher.precomputed(), s);
2610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharNoMatch(matcher.negate().precomputed(), s);
2620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharNoMatch(matcher.precomputed().negate(), s);
2630888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestOneCharNoMatch(CharMatcher matcher, String s) {
2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharNoMatch(matcher, s);
2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharMatch(matcher.negate(), s);
2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharNoMatch(matcher.precomputed(), s);
2690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharMatch(matcher.negate().precomputed(), s);
2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestOneCharMatch(matcher.precomputed().negate(), s);
2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestMatchThenNoMatch(CharMatcher matcher, String s) {
2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestMatchThenNoMatch(matcher, s);
2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatchThenMatch(matcher.negate(), s);
2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestMatchThenNoMatch(matcher.precomputed(), s);
2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatchThenMatch(matcher.negate().precomputed(), s);
2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatchThenMatch(matcher.precomputed().negate(), s);
2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestNoMatchThenMatch(CharMatcher matcher, String s) {
2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatchThenMatch(matcher, s);
2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestMatchThenNoMatch(matcher.negate(), s);
2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestNoMatchThenMatch(matcher.precomputed(), s);
2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestMatchThenNoMatch(matcher.negate().precomputed(), s);
2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    reallyTestMatchThenNoMatch(matcher.precomputed().negate(), s);
2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestOneCharMatch(CharMatcher matcher, String s) {
2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matches(s.charAt(0)));
2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.apply(s.charAt(0)));
2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s));
2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s, 0));
2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 1));
2950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.lastIndexIn(s));
2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAnyOf(s));
2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAllOf(s));
2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesNoneOf(s));
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.removeFrom(s));
3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("z", matcher.replaceFrom(s, 'z'));
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("ZZ", matcher.replaceFrom(s, "ZZ"));
3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", matcher.trimFrom(s));
3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.countIn(s));
3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestOneCharNoMatch(CharMatcher matcher, String s) {
3070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matches(s.charAt(0)));
3080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.apply(s.charAt(0)));
3090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s));
3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 0));
3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 1));
3120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.lastIndexIn(s));
3130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAnyOf(s));
3140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAllOf(s));
3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesNoneOf(s));
3160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(s, matcher.removeFrom(s));
3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(s, matcher.replaceFrom(s, 'z'));
3190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(s, matcher.replaceFrom(s, "ZZ"));
3200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(s, matcher.trimFrom(s));
3210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(0, matcher.countIn(s));
3220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) {
3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s));
3260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.indexIn(s, 0));
3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 1));
3280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 2));
3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, matcher.lastIndexIn(s));
3300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAnyOf(s));
3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAllOf(s));
3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesNoneOf(s));
3330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(1), matcher.removeFrom(s));
3340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("z" + s.substring(1), matcher.replaceFrom(s, 'z'));
3350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("ZZ" + s.substring(1), matcher.replaceFrom(s, "ZZ"));
3360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(1), matcher.trimFrom(s));
3370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.countIn(s));
3380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3390888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void reallyTestNoMatchThenMatch(CharMatcher matcher, String s) {
3410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.indexIn(s));
3420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.indexIn(s, 0));
3430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.indexIn(s, 1));
3440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(-1, matcher.indexIn(s, 2));
3450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.lastIndexIn(s));
3460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertTrue(matcher.matchesAnyOf(s));
3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesAllOf(s));
3480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertFalse(matcher.matchesNoneOf(s));
3490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(0, 1), matcher.removeFrom(s));
3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(0, 1) + "z", matcher.replaceFrom(s, 'z'));
3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(0, 1) + "ZZ", matcher.replaceFrom(s, "ZZ"));
3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(s.substring(0, 1), matcher.trimFrom(s));
3530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(1, matcher.countIn(s));
3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3550888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Checks that expected is equals to out, and further, if in is
3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * equals to expected, then out is successfully optimized to be
3590888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * identical to in, i.e. that "in" is simply returned.
3600888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
3610888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void assertEqualsSame(String expected, String in, String out) {
3620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (expected.equals(in)) {
3630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertSame(in, out);
3640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
3650888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals(expected, out);
3660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3670888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3690888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // Test collapse() a little differently than the rest, as we really want to
3700888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // cover lots of different configurations of input text
3710888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testCollapse() {
3720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // collapsing groups of '-' into '_' or '-'
3730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-", "_");
3740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x-", "x_");
3750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-x", "_x");
3760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("--", "_");
3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x--", "x_");
3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("--x", "_x");
3790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-x-", "_x_");
3800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x-x", "x_x");
3810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("---", "_");
3820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("--x-", "_x_");
3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("--xx", "_xx");
3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-x--", "_x_");
3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-x-x", "_x_x");
3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("-xx-", "_xx_");
3870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x--x", "x_x");
3880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x-x-", "x_x_");
3890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x-xx", "x_xx");
3900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapse("x-x--xx---x----x", "x_x_xx_x_x");
3910888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapseWithNoChange("");
3930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapseWithNoChange("x");
3940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestCollapseWithNoChange("xx");
3950888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3960888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3970888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestCollapse(String in, String out) {
3980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try a few different matchers which all match '-' and not 'x'
3990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try replacement chars that both do and do not change the value.
4000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (char replacement : new char[] { '_', '-' }) {
4010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      String expected = out.replace('_', replacement);
4020888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
4030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
4040888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('-').or(is('#')).collapseFrom(in, replacement));
4050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, isNot('x').collapseFrom(in, replacement));
4060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('x').negate().collapseFrom(in, replacement));
4070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-").collapseFrom(in, replacement));
4080888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-#").collapseFrom(in, replacement));
4090888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-#123").collapseFrom(in, replacement));
4100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4110888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4120888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4130888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestCollapseWithNoChange(String inout) {
4140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, is('-').collapseFrom(inout, '_'));
4150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
4160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, isNot('x').collapseFrom(inout, '_'));
4170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, is('x').negate().collapseFrom(inout, '_'));
4180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, anyOf("-").collapseFrom(inout, '_'));
4190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, anyOf("-#").collapseFrom(inout, '_'));
4200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, anyOf("-#123").collapseFrom(inout, '_'));
4210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
4220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4230888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testCollapse_any() {
4250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", CharMatcher.ANY.collapseFrom("", '_'));
4260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("_", CharMatcher.ANY.collapseFrom("a", '_'));
4270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("_", CharMatcher.ANY.collapseFrom("ab", '_'));
4280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("_", CharMatcher.ANY.collapseFrom("abcd", '_'));
4290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testTrimFrom() {
4320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // trimming -
4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-", "");
4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x-", "x");
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-x", "x");
4360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("--", "");
4370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x--", "x");
4380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("--x", "x");
4390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-x-", "x");
4400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x-x", "x-x");
4410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("---", "");
4420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("--x-", "x");
4430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("--xx", "xx");
4440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-x--", "x");
4450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-x-x", "x-x");
4460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("-xx-", "xx");
4470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x--x", "x--x");
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x-x-", "x-x");
4490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x-xx", "x-xx");
4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimFrom("x-x--xx---x----x", "x-x--xx---x----x");
4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // additional testing using the doc example
4520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("cat", anyOf("ab").trimFrom("abacatbab"));
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestTrimFrom(String in, String out) {
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try a few different matchers which all match '-' and not 'x'
4570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').trimFrom(in));
4580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').or(is('#')).trimFrom(in));
4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, isNot('x').trimFrom(in));
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('x').negate().trimFrom(in));
4610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-").trimFrom(in));
4620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#").trimFrom(in));
4630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#123").trimFrom(in));
4640888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4650888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4660888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testTrimLeadingFrom() {
4670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // trimming -
4680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-", "");
4690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x-", "x-");
4700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-x", "x");
4710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("--", "");
4720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x--", "x--");
4730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("--x", "x");
4740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-x-", "x-");
4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x-x", "x-x");
4760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("---", "");
4770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("--x-", "x-");
4780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("--xx", "xx");
4790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-x--", "x--");
4800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-x-x", "x-x");
4810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("-xx-", "xx-");
4820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x--x", "x--x");
4830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x-x-", "x-x-");
4840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x-xx", "x-xx");
4850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimLeadingFrom("x-x--xx---x----x", "x-x--xx---x----x");
4860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // additional testing using the doc example
4870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("catbab", anyOf("ab").trimLeadingFrom("abacatbab"));
4880888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4890888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4900888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestTrimLeadingFrom(String in, String out) {
4910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try a few different matchers which all match '-' and not 'x'
4920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').trimLeadingFrom(in));
4930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').or(is('#')).trimLeadingFrom(in));
4940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, isNot('x').trimLeadingFrom(in));
4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('x').negate().trimLeadingFrom(in));
4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#").trimLeadingFrom(in));
4970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#123").trimLeadingFrom(in));
4980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4990888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5000888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testTrimTrailingFrom() {
5010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // trimming -
5020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-", "");
5030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x-", "x");
5040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-x", "-x");
5050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("--", "");
5060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x--", "x");
5070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("--x", "--x");
5080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-x-", "-x");
5090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x-x", "x-x");
5100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("---", "");
5110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("--x-", "--x");
5120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("--xx", "--xx");
5130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-x--", "-x");
5140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-x-x", "-x-x");
5150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("-xx-", "-xx");
5160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x--x", "x--x");
5170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x-x-", "x-x");
5180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x-xx", "x-xx");
5190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimTrailingFrom("x-x--xx---x----x", "x-x--xx---x----x");
5200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // additional testing using the doc example
5210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("abacat", anyOf("ab").trimTrailingFrom("abacatbab"));
5220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5230888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestTrimTrailingFrom(String in, String out) {
5250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try a few different matchers which all match '-' and not 'x'
5260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').trimTrailingFrom(in));
5270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('-').or(is('#')).trimTrailingFrom(in));
5280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, isNot('x').trimTrailingFrom(in));
5290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, is('x').negate().trimTrailingFrom(in));
5300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#").trimTrailingFrom(in));
5310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(out, anyOf("-#123").trimTrailingFrom(in));
5320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5330888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5340888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testTrimAndCollapse() {
5350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // collapsing groups of '-' into '_' or '-'
5360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("", "");
5370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x", "x");
5380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-", "");
5390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x-", "x");
5400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-x", "x");
5410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("--", "");
5420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x--", "x");
5430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("--x", "x");
5440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-x-", "x");
5450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x-x", "x_x");
5460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("---", "");
5470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("--x-", "x");
5480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("--xx", "xx");
5490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-x--", "x");
5500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-x-x", "x_x");
5510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("-xx-", "xx");
5520888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x--x", "x_x");
5530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x-x-", "x_x");
5540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x-xx", "x_xx");
5550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    doTestTrimAndCollapse("x-x--xx---x----x", "x_x_xx_x_x");
5560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5570888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5580888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void doTestTrimAndCollapse(String in, String out) {
5590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Try a few different matchers which all match '-' and not 'x'
5600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (char replacement : new char[] { '_', '-' }) {
5610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      String expected = out.replace('_', replacement);
5620888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('-').trimAndCollapseFrom(in, replacement));
5630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('-').or(is('#')).trimAndCollapseFrom(in, replacement));
5640888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, isNot('x').trimAndCollapseFrom(in, replacement));
5650888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, is('x').negate().trimAndCollapseFrom(in, replacement));
5660888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-").trimAndCollapseFrom(in, replacement));
5670888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-#").trimAndCollapseFrom(in, replacement));
5680888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEqualsSame(expected, in, anyOf("-#123").trimAndCollapseFrom(in, replacement));
5690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
5700888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5710888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5720888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testReplaceFrom() {
5730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("yoho", is('a').replaceFrom("yaha", 'o'));
5740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("yh", is('a').replaceFrom("yaha", ""));
5750888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("yoho", is('a').replaceFrom("yaha", "o"));
5760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("yoohoo", is('a').replaceFrom("yaha", "oo"));
5770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("12 &gt; 5", is('>').replaceFrom("12 > 5", "&gt;"));
5780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testPrecomputedOptimizations() {
5810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // These are testing behavior that's never promised by the API.
5820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Some matchers are so efficient that it is a waste of effort to
5830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // build a precomputed version.
5840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    CharMatcher m1 = is('x');
5850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m1, m1.precomputed());
5860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m1.toString(), m1.precomputed().toString());
5870888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    CharMatcher m2 = anyOf("Az");
5890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m2, m2.precomputed());
5900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m2.toString(), m2.precomputed().toString());
5910888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    CharMatcher m3 = inRange('A', 'Z');
5930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m3, m3.precomputed());
5940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(m3.toString(), m3.precomputed().toString());
5950888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.NONE, CharMatcher.NONE.precomputed());
5970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(CharMatcher.ANY, CharMatcher.ANY.precomputed());
5980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6000888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static void checkExactMatches(CharMatcher m, char[] chars) {
6010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Character> positive = Sets.newHashSetWithExpectedSize(chars.length);
6020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int i = 0; i < chars.length; i++) {
6030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      positive.add(chars[i]);
6040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int c = 0; c <= Character.MAX_VALUE; c++) {
6060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertFalse(positive.contains(new Character((char) c)) ^ m.matches((char) c));
6070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6090888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6100888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static char[] randomChars(Random rand, int size) {
6110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Character> chars = new HashSet<Character>(size);
6120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (int i = 0; i < size; i++) {
6130888a09821a98ac0680fad765217302858e70fa4Paul Duffin      char c;
6140888a09821a98ac0680fad765217302858e70fa4Paul Duffin      while (true) {
6150888a09821a98ac0680fad765217302858e70fa4Paul Duffin        c = (char) rand.nextInt(Character.MAX_VALUE - Character.MIN_VALUE + 1);
6160888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (!chars.contains(c)) {
6170888a09821a98ac0680fad765217302858e70fa4Paul Duffin          break;
6180888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
6190888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
6200888a09821a98ac0680fad765217302858e70fa4Paul Duffin      chars.add(c);
6210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    char[] retValue = new char[chars.size()];
6230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int i = 0;
6240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (char c : chars) {
6250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      retValue[i++] = c;
6260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
6270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Arrays.sort(retValue);
6280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return retValue;
6290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testToString() {
6320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.NONE", CharMatcher.anyOf(""));
6330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.is('\\u0031')", CharMatcher.anyOf("1"));
6340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.isNot('\\u0031')", CharMatcher.isNot('1'));
6350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\")", CharMatcher.anyOf("12"));
6360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")",
6370888a09821a98ac0680fad765217302858e70fa4Paul Duffin        CharMatcher.anyOf("321"));
6380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertToStringWorks("CharMatcher.inRange('\\u0031', '\\u0033')",
6390888a09821a98ac0680fad765217302858e70fa4Paul Duffin        CharMatcher.inRange('1', '3'));
6400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6410888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6420888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static void assertToStringWorks(String expected, CharMatcher matcher) {
6430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, matcher.toString());
6440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, matcher.precomputed().toString());
6450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, matcher.negate().negate().toString());
6460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, matcher.negate().precomputed().negate().toString());
6470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, matcher.negate().precomputed().negate().precomputed().toString());
6480888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
6490888a09821a98ac0680fad765217302858e70fa4Paul Duffin}
6500888a09821a98ac0680fad765217302858e70fa4Paul Duffin
651