• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.base;
18 
19 import static com.google.common.base.CharMatcher.anyOf;
20 import static com.google.common.base.CharMatcher.forPredicate;
21 import static com.google.common.base.CharMatcher.inRange;
22 import static com.google.common.base.CharMatcher.is;
23 import static com.google.common.base.CharMatcher.isNot;
24 import static com.google.common.base.CharMatcher.noneOf;
25 
26 import com.google.common.annotations.GwtCompatible;
27 import com.google.common.annotations.GwtIncompatible;
28 import com.google.common.testing.NullPointerTester;
29 
30 import junit.framework.AssertionFailedError;
31 import junit.framework.TestCase;
32 
33 /**
34  * Unit test for {@link CharMatcher}.
35  *
36  * @author Kevin Bourrillion
37  */
38 @GwtCompatible(emulated = true)
39 public class CharMatcherTest extends TestCase {
40 
41   @GwtIncompatible("NullPointerTester")
testStaticNullPointers()42   public void testStaticNullPointers() throws Exception {
43     NullPointerTester tester = new NullPointerTester();
44     tester.testAllPublicStaticMethods(CharMatcher.class);
45     tester.testAllPublicInstanceMethods(CharMatcher.ANY);
46     tester.testAllPublicInstanceMethods(CharMatcher.anyOf("abc"));
47   }
48 
49   private static final CharMatcher WHATEVER = new CharMatcher() {
50     @Override public boolean matches(char c) {
51       throw new AssertionFailedError(
52           "You weren't supposed to actually invoke me!");
53     }
54   };
55 
testAnyAndNone_logicalOps()56   public void testAnyAndNone_logicalOps() throws Exception {
57     // These are testing behavior that's never promised by the API, but since
58     // we're lucky enough that these do pass, it saves us from having to write
59     // more excruciating tests! Hooray!
60 
61     assertSame(CharMatcher.ANY, CharMatcher.NONE.negate());
62     assertSame(CharMatcher.NONE, CharMatcher.ANY.negate());
63 
64     assertSame(WHATEVER, CharMatcher.ANY.and(WHATEVER));
65     assertSame(CharMatcher.ANY, CharMatcher.ANY.or(WHATEVER));
66 
67     assertSame(CharMatcher.NONE, CharMatcher.NONE.and(WHATEVER));
68     assertSame(WHATEVER, CharMatcher.NONE.or(WHATEVER));
69   }
70 
71   // The rest of the behavior of ANY and NONE will be covered in the tests for
72   // the text processing methods below.
73 
74   // The next tests require ICU4J and have, at least for now, been sliced out
75   // of the open-source view of the tests.
76 
77   @GwtIncompatible("Character.isISOControl")
testJavaIsoControl()78   public void testJavaIsoControl() {
79     for (int c = 0; c <= Character.MAX_VALUE; c++) {
80       assertEquals("" + c, Character.isISOControl(c),
81           CharMatcher.JAVA_ISO_CONTROL.matches((char) c));
82     }
83   }
84 
85   // There's no way to test LEGACY_WHITESPACE, really; it just is what it is.
86 
87   // Omitting tests for the rest of the JAVA_* constants as these are defined
88   // as extremely straightforward pass-throughs to the JDK methods.
89 
90   // We're testing the is(), isNot(), anyOf(), noneOf() and inRange() methods
91   // below by testing their text-processing methods.
92 
93   // The organization of this test class is unusual, as it's not done by
94   // method, but by overall "scenario". Also, the variety of actual tests we
95   // do borders on absurd overkill. Better safe than sorry, though?
96 
testEmpty()97   public void testEmpty() throws Exception {
98     doTestEmpty(CharMatcher.ANY);
99     doTestEmpty(CharMatcher.NONE);
100     doTestEmpty(is('a'));
101     doTestEmpty(isNot('a'));
102     doTestEmpty(anyOf(""));
103     doTestEmpty(anyOf("x"));
104     doTestEmpty(anyOf("xy"));
105     doTestEmpty(anyOf("CharMatcher"));
106     doTestEmpty(noneOf("CharMatcher"));
107     doTestEmpty(inRange('n', 'q'));
108     doTestEmpty(forPredicate(Predicates.equalTo('c')));
109   }
110 
111   @GwtIncompatible("NullPointerTester")
testNull()112   public void testNull() throws Exception {
113     doTestNull(CharMatcher.ANY);
114     doTestNull(CharMatcher.NONE);
115     doTestNull(is('a'));
116     doTestNull(isNot('a'));
117     doTestNull(anyOf(""));
118     doTestNull(anyOf("x"));
119     doTestNull(anyOf("xy"));
120     doTestNull(anyOf("CharMatcher"));
121     doTestNull(noneOf("CharMatcher"));
122     doTestNull(inRange('n', 'q'));
123     doTestNull(forPredicate(Predicates.equalTo('c')));
124   }
125 
doTestEmpty(CharMatcher matcher)126   private void doTestEmpty(CharMatcher matcher) throws Exception {
127     reallyTestEmpty(matcher);
128     reallyTestEmpty(matcher.negate());
129     reallyTestEmpty(matcher.precomputed());
130   }
131 
reallyTestEmpty(CharMatcher matcher)132   private void reallyTestEmpty(CharMatcher matcher) throws Exception {
133     assertEquals(-1, matcher.indexIn(""));
134     assertEquals(-1, matcher.indexIn("", 0));
135     try {
136       matcher.indexIn("", 1);
137       fail();
138     } catch (IndexOutOfBoundsException expected) {
139     }
140     try {
141       matcher.indexIn("", -1);
142       fail();
143     } catch (IndexOutOfBoundsException expected) {
144     }
145     assertEquals(-1, matcher.lastIndexIn(""));
146     assertFalse(matcher.matchesAnyOf(""));
147     assertTrue(matcher.matchesAllOf(""));
148     assertTrue(matcher.matchesNoneOf(""));
149     assertEquals("", matcher.removeFrom(""));
150     assertEquals("", matcher.replaceFrom("", 'z'));
151     assertEquals("", matcher.replaceFrom("", "ZZ"));
152     assertEquals("", matcher.trimFrom(""));
153     assertEquals(0, matcher.countIn(""));
154   }
155 
156   @GwtIncompatible("NullPointerTester")
doTestNull(CharMatcher matcher)157   private void doTestNull(CharMatcher matcher) throws Exception {
158     NullPointerTester tester = new NullPointerTester();
159     tester.testAllPublicInstanceMethods(matcher);
160   }
161 
testNoMatches()162   public void testNoMatches() {
163     doTestNoMatches(CharMatcher.NONE, "blah");
164     doTestNoMatches(is('a'), "bcde");
165     doTestNoMatches(isNot('a'), "aaaa");
166     doTestNoMatches(anyOf(""), "abcd");
167     doTestNoMatches(anyOf("x"), "abcd");
168     doTestNoMatches(anyOf("xy"), "abcd");
169     doTestNoMatches(anyOf("CharMatcher"), "zxqy");
170     doTestNoMatches(noneOf("CharMatcher"), "ChMa");
171     doTestNoMatches(inRange('p', 'x'), "mom");
172     doTestNoMatches(forPredicate(Predicates.equalTo('c')), "abe");
173     doTestNoMatches(inRange('A', 'Z').and(inRange('F', 'K').negate()), "F1a");
174     doTestNoMatches(CharMatcher.DIGIT, "\tAz()");
175     doTestNoMatches(CharMatcher.JAVA_DIGIT, "\tAz()");
176     doTestNoMatches(CharMatcher.DIGIT.and(CharMatcher.ASCII), "\tAz()");
177     doTestNoMatches(CharMatcher.SINGLE_WIDTH, "\u05bf\u3000");
178   }
179 
doTestNoMatches(CharMatcher matcher, String s)180   private void doTestNoMatches(CharMatcher matcher, String s) {
181     reallyTestNoMatches(matcher, s);
182     reallyTestAllMatches(matcher.negate(), s);
183     reallyTestNoMatches(matcher.precomputed(), s);
184     reallyTestAllMatches(matcher.negate().precomputed(), s);
185     reallyTestAllMatches(matcher.precomputed().negate(), s);
186     reallyTestNoMatches(forPredicate(matcher), s);
187 
188     reallyTestNoMatches(matcher, new StringBuilder(s));
189   }
190 
testAllMatches()191   public void testAllMatches() {
192     doTestAllMatches(CharMatcher.ANY, "blah");
193     doTestAllMatches(isNot('a'), "bcde");
194     doTestAllMatches(is('a'), "aaaa");
195     doTestAllMatches(noneOf("CharMatcher"), "zxqy");
196     doTestAllMatches(anyOf("x"), "xxxx");
197     doTestAllMatches(anyOf("xy"), "xyyx");
198     doTestAllMatches(anyOf("CharMatcher"), "ChMa");
199     doTestAllMatches(inRange('m', 'p'), "mom");
200     doTestAllMatches(forPredicate(Predicates.equalTo('c')), "ccc");
201     doTestAllMatches(CharMatcher.DIGIT, "0123456789\u0ED0\u1B59");
202     doTestAllMatches(CharMatcher.JAVA_DIGIT, "0123456789");
203     doTestAllMatches(CharMatcher.DIGIT.and(CharMatcher.ASCII), "0123456789");
204     doTestAllMatches(CharMatcher.SINGLE_WIDTH, "\t0123ABCdef~\u00A0\u2111");
205   }
206 
doTestAllMatches(CharMatcher matcher, String s)207   private void doTestAllMatches(CharMatcher matcher, String s) {
208     reallyTestAllMatches(matcher, s);
209     reallyTestNoMatches(matcher.negate(), s);
210     reallyTestAllMatches(matcher.precomputed(), s);
211     reallyTestNoMatches(matcher.negate().precomputed(), s);
212     reallyTestNoMatches(matcher.precomputed().negate(), s);
213     reallyTestAllMatches(forPredicate(matcher), s);
214 
215     reallyTestAllMatches(matcher, new StringBuilder(s));
216   }
217 
reallyTestNoMatches(CharMatcher matcher, CharSequence s)218   private void reallyTestNoMatches(CharMatcher matcher, CharSequence s) {
219     assertFalse(matcher.matches(s.charAt(0)));
220     assertEquals(-1, matcher.indexIn(s));
221     assertEquals(-1, matcher.indexIn(s, 0));
222     assertEquals(-1, matcher.indexIn(s, 1));
223     assertEquals(-1, matcher.indexIn(s, s.length()));
224     try {
225       matcher.indexIn(s, s.length() + 1);
226       fail();
227     } catch (IndexOutOfBoundsException expected) {
228     }
229     try {
230       matcher.indexIn(s, -1);
231       fail();
232     } catch (IndexOutOfBoundsException expected) {
233     }
234     assertEquals(-1, matcher.lastIndexIn(s));
235     assertFalse(matcher.matchesAnyOf(s));
236     assertFalse(matcher.matchesAllOf(s));
237     assertTrue(matcher.matchesNoneOf(s));
238 
239     assertEquals(s.toString(), matcher.removeFrom(s));
240     assertEquals(s.toString(), matcher.replaceFrom(s, 'z'));
241     assertEquals(s.toString(), matcher.replaceFrom(s, "ZZ"));
242     assertEquals(s.toString(), matcher.trimFrom(s));
243     assertEquals(0, matcher.countIn(s));
244   }
245 
reallyTestAllMatches(CharMatcher matcher, CharSequence s)246   private void reallyTestAllMatches(CharMatcher matcher, CharSequence s) {
247     assertTrue(matcher.matches(s.charAt(0)));
248     assertEquals(0, matcher.indexIn(s));
249     assertEquals(0, matcher.indexIn(s, 0));
250     assertEquals(1, matcher.indexIn(s, 1));
251     assertEquals(-1, matcher.indexIn(s, s.length()));
252     assertEquals(s.length() - 1, matcher.lastIndexIn(s));
253     assertTrue(matcher.matchesAnyOf(s));
254     assertTrue(matcher.matchesAllOf(s));
255     assertFalse(matcher.matchesNoneOf(s));
256     assertEquals("", matcher.removeFrom(s));
257     assertEquals(Strings.repeat("z", s.length()),
258         matcher.replaceFrom(s, 'z'));
259     assertEquals(Strings.repeat("ZZ", s.length()),
260         matcher.replaceFrom(s, "ZZ"));
261     assertEquals("", matcher.trimFrom(s));
262     assertEquals(s.length(), matcher.countIn(s));
263   }
264 
testGeneral()265   public void testGeneral() {
266     doTestGeneral(is('a'), 'a', 'b');
267     doTestGeneral(isNot('a'), 'b', 'a');
268     doTestGeneral(anyOf("x"), 'x', 'z');
269     doTestGeneral(anyOf("xy"), 'y', 'z');
270     doTestGeneral(anyOf("CharMatcher"), 'C', 'z');
271     doTestGeneral(noneOf("CharMatcher"), 'z', 'C');
272     doTestGeneral(inRange('p', 'x'), 'q', 'z');
273   }
274 
doTestGeneral(CharMatcher matcher, char match, char noMatch)275   private void doTestGeneral(CharMatcher matcher, char match, char noMatch) {
276     doTestOneCharMatch(matcher, "" + match);
277     doTestOneCharNoMatch(matcher, "" + noMatch);
278     doTestMatchThenNoMatch(matcher, "" + match + noMatch);
279     doTestNoMatchThenMatch(matcher, "" + noMatch + match);
280   }
281 
doTestOneCharMatch(CharMatcher matcher, String s)282   private void doTestOneCharMatch(CharMatcher matcher, String s) {
283     reallyTestOneCharMatch(matcher, s);
284     reallyTestOneCharNoMatch(matcher.negate(), s);
285     reallyTestOneCharMatch(matcher.precomputed(), s);
286     reallyTestOneCharNoMatch(matcher.negate().precomputed(), s);
287     reallyTestOneCharNoMatch(matcher.precomputed().negate(), s);
288   }
289 
doTestOneCharNoMatch(CharMatcher matcher, String s)290   private void doTestOneCharNoMatch(CharMatcher matcher, String s) {
291     reallyTestOneCharNoMatch(matcher, s);
292     reallyTestOneCharMatch(matcher.negate(), s);
293     reallyTestOneCharNoMatch(matcher.precomputed(), s);
294     reallyTestOneCharMatch(matcher.negate().precomputed(), s);
295     reallyTestOneCharMatch(matcher.precomputed().negate(), s);
296   }
297 
doTestMatchThenNoMatch(CharMatcher matcher, String s)298   private void doTestMatchThenNoMatch(CharMatcher matcher, String s) {
299     reallyTestMatchThenNoMatch(matcher, s);
300     reallyTestNoMatchThenMatch(matcher.negate(), s);
301     reallyTestMatchThenNoMatch(matcher.precomputed(), s);
302     reallyTestNoMatchThenMatch(matcher.negate().precomputed(), s);
303     reallyTestNoMatchThenMatch(matcher.precomputed().negate(), s);
304   }
305 
doTestNoMatchThenMatch(CharMatcher matcher, String s)306   private void doTestNoMatchThenMatch(CharMatcher matcher, String s) {
307     reallyTestNoMatchThenMatch(matcher, s);
308     reallyTestMatchThenNoMatch(matcher.negate(), s);
309     reallyTestNoMatchThenMatch(matcher.precomputed(), s);
310     reallyTestMatchThenNoMatch(matcher.negate().precomputed(), s);
311     reallyTestMatchThenNoMatch(matcher.precomputed().negate(), s);
312   }
313 
reallyTestOneCharMatch(CharMatcher matcher, String s)314   private void reallyTestOneCharMatch(CharMatcher matcher, String s) {
315     assertTrue(matcher.matches(s.charAt(0)));
316     assertTrue(matcher.apply(s.charAt(0)));
317     assertEquals(0, matcher.indexIn(s));
318     assertEquals(0, matcher.indexIn(s, 0));
319     assertEquals(-1, matcher.indexIn(s, 1));
320     assertEquals(0, matcher.lastIndexIn(s));
321     assertTrue(matcher.matchesAnyOf(s));
322     assertTrue(matcher.matchesAllOf(s));
323     assertFalse(matcher.matchesNoneOf(s));
324     assertEquals("", matcher.removeFrom(s));
325     assertEquals("z", matcher.replaceFrom(s, 'z'));
326     assertEquals("ZZ", matcher.replaceFrom(s, "ZZ"));
327     assertEquals("", matcher.trimFrom(s));
328     assertEquals(1, matcher.countIn(s));
329   }
330 
reallyTestOneCharNoMatch(CharMatcher matcher, String s)331   private void reallyTestOneCharNoMatch(CharMatcher matcher, String s) {
332     assertFalse(matcher.matches(s.charAt(0)));
333     assertFalse(matcher.apply(s.charAt(0)));
334     assertEquals(-1, matcher.indexIn(s));
335     assertEquals(-1, matcher.indexIn(s, 0));
336     assertEquals(-1, matcher.indexIn(s, 1));
337     assertEquals(-1, matcher.lastIndexIn(s));
338     assertFalse(matcher.matchesAnyOf(s));
339     assertFalse(matcher.matchesAllOf(s));
340     assertTrue(matcher.matchesNoneOf(s));
341 
342     // Note: only 'assertEquals' is promised by the API.  Although they could
343     // have been assertSame() on the server side, they have to be assertEquals
344     // in GWT, because of GWT issue 4491.
345     assertEquals(s, matcher.removeFrom(s));
346     assertEquals(s, matcher.replaceFrom(s, 'z'));
347     assertEquals(s, matcher.replaceFrom(s, "ZZ"));
348     assertEquals(s, matcher.trimFrom(s));
349     assertEquals(0, matcher.countIn(s));
350   }
351 
reallyTestMatchThenNoMatch(CharMatcher matcher, String s)352   private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) {
353     assertEquals(0, matcher.indexIn(s));
354     assertEquals(0, matcher.indexIn(s, 0));
355     assertEquals(-1, matcher.indexIn(s, 1));
356     assertEquals(-1, matcher.indexIn(s, 2));
357     assertEquals(0, matcher.lastIndexIn(s));
358     assertTrue(matcher.matchesAnyOf(s));
359     assertFalse(matcher.matchesAllOf(s));
360     assertFalse(matcher.matchesNoneOf(s));
361     assertEquals(s.substring(1), matcher.removeFrom(s));
362     assertEquals("z" + s.substring(1), matcher.replaceFrom(s, 'z'));
363     assertEquals("ZZ" + s.substring(1), matcher.replaceFrom(s, "ZZ"));
364     assertEquals(s.substring(1), matcher.trimFrom(s));
365     assertEquals(1, matcher.countIn(s));
366   }
367 
reallyTestNoMatchThenMatch(CharMatcher matcher, String s)368   private void reallyTestNoMatchThenMatch(CharMatcher matcher, String s) {
369     assertEquals(1, matcher.indexIn(s));
370     assertEquals(1, matcher.indexIn(s, 0));
371     assertEquals(1, matcher.indexIn(s, 1));
372     assertEquals(-1, matcher.indexIn(s, 2));
373     assertEquals(1, matcher.lastIndexIn(s));
374     assertTrue(matcher.matchesAnyOf(s));
375     assertFalse(matcher.matchesAllOf(s));
376     assertFalse(matcher.matchesNoneOf(s));
377     assertEquals(s.substring(0, 1), matcher.removeFrom(s));
378     assertEquals(s.substring(0, 1) + "z", matcher.replaceFrom(s, 'z'));
379     assertEquals(s.substring(0, 1) + "ZZ", matcher.replaceFrom(s, "ZZ"));
380     assertEquals(s.substring(0, 1), matcher.trimFrom(s));
381     assertEquals(1, matcher.countIn(s));
382   }
383 
384   // Test collapse() a little differently than the rest, as we really want to
385   // cover lots of different configurations of input text
testCollapse()386   public void testCollapse() {
387     // collapsing groups of - into _
388     doTestCollapse("-", "_");
389     doTestCollapse("x-", "x_");
390     doTestCollapse("-x", "_x");
391     doTestCollapse("--", "_");
392     doTestCollapse("x--", "x_");
393     doTestCollapse("--x", "_x");
394     doTestCollapse("-x-", "_x_");
395     doTestCollapse("x-x", "x_x");
396     doTestCollapse("---", "_");
397     doTestCollapse("--x-", "_x_");
398     doTestCollapse("--xx", "_xx");
399     doTestCollapse("-x--", "_x_");
400     doTestCollapse("-x-x", "_x_x");
401     doTestCollapse("-xx-", "_xx_");
402     doTestCollapse("x--x", "x_x");
403     doTestCollapse("x-x-", "x_x_");
404     doTestCollapse("x-xx", "x_xx");
405     doTestCollapse("x-x--xx---x----x", "x_x_xx_x_x");
406 
407     doTestCollapseWithNoChange("");
408     doTestCollapseWithNoChange("x");
409     doTestCollapseWithNoChange("xx");
410   }
411 
doTestCollapse(String in, String out)412   private void doTestCollapse(String in, String out) {
413     // Try a few different matchers which all match '-' and not 'x'
414     assertEquals(out, is('-').collapseFrom(in, '_'));
415     assertEquals(out, is('-').or(is('#')).collapseFrom(in, '_'));
416     assertEquals(out, isNot('x').collapseFrom(in, '_'));
417     assertEquals(out, is('x').negate().collapseFrom(in, '_'));
418     assertEquals(out, anyOf("-").collapseFrom(in, '_'));
419     assertEquals(out, anyOf("-#").collapseFrom(in, '_'));
420     assertEquals(out, anyOf("-#123").collapseFrom(in, '_'));
421   }
422 
doTestCollapseWithNoChange(String inout)423   private void doTestCollapseWithNoChange(String inout) {
424     /*
425      * Note: assertSame(), not promised by the spec, happens to work with the
426      * current implementation because String.toString() promises to return
427      * |this|. However, GWT bug 4491 keeps it from working there, so we stick
428      * with assertEquals().
429      */
430     assertEquals(inout, is('-').collapseFrom(inout, '_'));
431     assertEquals(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
432     assertEquals(inout, isNot('x').collapseFrom(inout, '_'));
433     assertEquals(inout, is('x').negate().collapseFrom(inout, '_'));
434     assertEquals(inout, anyOf("-").collapseFrom(inout, '_'));
435     assertEquals(inout, anyOf("-#").collapseFrom(inout, '_'));
436     assertEquals(inout, anyOf("-#123").collapseFrom(inout, '_'));
437     assertEquals(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
438   }
439 
testCollapse_any()440   public void testCollapse_any() {
441     assertEquals("", CharMatcher.ANY.collapseFrom("", '_'));
442     assertEquals("_", CharMatcher.ANY.collapseFrom("a", '_'));
443     assertEquals("_", CharMatcher.ANY.collapseFrom("ab", '_'));
444     assertEquals("_", CharMatcher.ANY.collapseFrom("abcd", '_'));
445   }
446 
testTrimFrom()447   public void testTrimFrom() {
448     // trimming -
449     doTestTrimFrom("-", "");
450     doTestTrimFrom("x-", "x");
451     doTestTrimFrom("-x", "x");
452     doTestTrimFrom("--", "");
453     doTestTrimFrom("x--", "x");
454     doTestTrimFrom("--x", "x");
455     doTestTrimFrom("-x-", "x");
456     doTestTrimFrom("x-x", "x-x");
457     doTestTrimFrom("---", "");
458     doTestTrimFrom("--x-", "x");
459     doTestTrimFrom("--xx", "xx");
460     doTestTrimFrom("-x--", "x");
461     doTestTrimFrom("-x-x", "x-x");
462     doTestTrimFrom("-xx-", "xx");
463     doTestTrimFrom("x--x", "x--x");
464     doTestTrimFrom("x-x-", "x-x");
465     doTestTrimFrom("x-xx", "x-xx");
466     doTestTrimFrom("x-x--xx---x----x", "x-x--xx---x----x");
467     // additional testing using the doc example
468     assertEquals("cat", anyOf("ab").trimFrom("abacatbab"));
469   }
470 
doTestTrimFrom(String in, String out)471   private void doTestTrimFrom(String in, String out) {
472     // Try a few different matchers which all match '-' and not 'x'
473     assertEquals(out, is('-').trimFrom(in));
474     assertEquals(out, is('-').or(is('#')).trimFrom(in));
475     assertEquals(out, isNot('x').trimFrom(in));
476     assertEquals(out, is('x').negate().trimFrom(in));
477     assertEquals(out, anyOf("-").trimFrom(in));
478     assertEquals(out, anyOf("-#").trimFrom(in));
479     assertEquals(out, anyOf("-#123").trimFrom(in));
480   }
481 
testTrimLeadingFrom()482   public void testTrimLeadingFrom() {
483     // trimming -
484     doTestTrimLeadingFrom("-", "");
485     doTestTrimLeadingFrom("x-", "x-");
486     doTestTrimLeadingFrom("-x", "x");
487     doTestTrimLeadingFrom("--", "");
488     doTestTrimLeadingFrom("x--", "x--");
489     doTestTrimLeadingFrom("--x", "x");
490     doTestTrimLeadingFrom("-x-", "x-");
491     doTestTrimLeadingFrom("x-x", "x-x");
492     doTestTrimLeadingFrom("---", "");
493     doTestTrimLeadingFrom("--x-", "x-");
494     doTestTrimLeadingFrom("--xx", "xx");
495     doTestTrimLeadingFrom("-x--", "x--");
496     doTestTrimLeadingFrom("-x-x", "x-x");
497     doTestTrimLeadingFrom("-xx-", "xx-");
498     doTestTrimLeadingFrom("x--x", "x--x");
499     doTestTrimLeadingFrom("x-x-", "x-x-");
500     doTestTrimLeadingFrom("x-xx", "x-xx");
501     doTestTrimLeadingFrom("x-x--xx---x----x", "x-x--xx---x----x");
502     // additional testing using the doc example
503     assertEquals("catbab", anyOf("ab").trimLeadingFrom("abacatbab"));
504   }
505 
doTestTrimLeadingFrom(String in, String out)506   private void doTestTrimLeadingFrom(String in, String out) {
507     // Try a few different matchers which all match '-' and not 'x'
508     assertEquals(out, is('-').trimLeadingFrom(in));
509     assertEquals(out, is('-').or(is('#')).trimLeadingFrom(in));
510     assertEquals(out, isNot('x').trimLeadingFrom(in));
511     assertEquals(out, is('x').negate().trimLeadingFrom(in));
512     assertEquals(out, anyOf("-#").trimLeadingFrom(in));
513     assertEquals(out, anyOf("-#123").trimLeadingFrom(in));
514   }
515 
testTrimTrailingFrom()516   public void testTrimTrailingFrom() {
517     // trimming -
518     doTestTrimTrailingFrom("-", "");
519     doTestTrimTrailingFrom("x-", "x");
520     doTestTrimTrailingFrom("-x", "-x");
521     doTestTrimTrailingFrom("--", "");
522     doTestTrimTrailingFrom("x--", "x");
523     doTestTrimTrailingFrom("--x", "--x");
524     doTestTrimTrailingFrom("-x-", "-x");
525     doTestTrimTrailingFrom("x-x", "x-x");
526     doTestTrimTrailingFrom("---", "");
527     doTestTrimTrailingFrom("--x-", "--x");
528     doTestTrimTrailingFrom("--xx", "--xx");
529     doTestTrimTrailingFrom("-x--", "-x");
530     doTestTrimTrailingFrom("-x-x", "-x-x");
531     doTestTrimTrailingFrom("-xx-", "-xx");
532     doTestTrimTrailingFrom("x--x", "x--x");
533     doTestTrimTrailingFrom("x-x-", "x-x");
534     doTestTrimTrailingFrom("x-xx", "x-xx");
535     doTestTrimTrailingFrom("x-x--xx---x----x", "x-x--xx---x----x");
536     // additional testing using the doc example
537     assertEquals("abacat", anyOf("ab").trimTrailingFrom("abacatbab"));
538   }
539 
doTestTrimTrailingFrom(String in, String out)540   private void doTestTrimTrailingFrom(String in, String out) {
541     // Try a few different matchers which all match '-' and not 'x'
542     assertEquals(out, is('-').trimTrailingFrom(in));
543     assertEquals(out, is('-').or(is('#')).trimTrailingFrom(in));
544     assertEquals(out, isNot('x').trimTrailingFrom(in));
545     assertEquals(out, is('x').negate().trimTrailingFrom(in));
546     assertEquals(out, anyOf("-#").trimTrailingFrom(in));
547     assertEquals(out, anyOf("-#123").trimTrailingFrom(in));
548   }
549 
testTrimAndCollapse()550   public void testTrimAndCollapse() {
551     // collapsing groups of - into _
552     doTestTrimAndCollapse("-", "");
553     doTestTrimAndCollapse("x-", "x");
554     doTestTrimAndCollapse("-x", "x");
555     doTestTrimAndCollapse("--", "");
556     doTestTrimAndCollapse("x--", "x");
557     doTestTrimAndCollapse("--x", "x");
558     doTestTrimAndCollapse("-x-", "x");
559     doTestTrimAndCollapse("x-x", "x_x");
560     doTestTrimAndCollapse("---", "");
561     doTestTrimAndCollapse("--x-", "x");
562     doTestTrimAndCollapse("--xx", "xx");
563     doTestTrimAndCollapse("-x--", "x");
564     doTestTrimAndCollapse("-x-x", "x_x");
565     doTestTrimAndCollapse("-xx-", "xx");
566     doTestTrimAndCollapse("x--x", "x_x");
567     doTestTrimAndCollapse("x-x-", "x_x");
568     doTestTrimAndCollapse("x-xx", "x_xx");
569     doTestTrimAndCollapse("x-x--xx---x----x", "x_x_xx_x_x");
570   }
571 
doTestTrimAndCollapse(String in, String out)572   private void doTestTrimAndCollapse(String in, String out) {
573     // Try a few different matchers which all match '-' and not 'x'
574     assertEquals(out, is('-').trimAndCollapseFrom(in, '_'));
575     assertEquals(out, is('-').or(is('#')).trimAndCollapseFrom(in, '_'));
576     assertEquals(out, isNot('x').trimAndCollapseFrom(in, '_'));
577     assertEquals(out, is('x').negate().trimAndCollapseFrom(in, '_'));
578     assertEquals(out, anyOf("-").trimAndCollapseFrom(in, '_'));
579     assertEquals(out, anyOf("-#").trimAndCollapseFrom(in, '_'));
580     assertEquals(out, anyOf("-#123").trimAndCollapseFrom(in, '_'));
581   }
582 
testReplaceFrom()583   public void testReplaceFrom() {
584     assertEquals("yoho", is('a').replaceFrom("yaha", 'o'));
585     assertEquals("yh", is('a').replaceFrom("yaha", ""));
586     assertEquals("yoho", is('a').replaceFrom("yaha", "o"));
587     assertEquals("yoohoo", is('a').replaceFrom("yaha", "oo"));
588     assertEquals("12 &gt; 5", is('>').replaceFrom("12 > 5", "&gt;"));
589   }
590 
testPrecomputedOptimizations()591   public void testPrecomputedOptimizations() {
592     // These are testing behavior that's never promised by the API.
593     // Some matchers are so efficient that it is a waste of effort to
594     // build a precomputed version.
595     CharMatcher m1 = is('x');
596     assertSame(m1, m1.precomputed());
597 
598     CharMatcher m2 = anyOf("Az");
599     assertSame(m2, m2.precomputed());
600 
601     CharMatcher m3 = inRange('A', 'Z');
602     assertSame(m3, m3.precomputed());
603 
604     assertSame(CharMatcher.NONE, CharMatcher.NONE.precomputed());
605     assertSame(CharMatcher.ANY, CharMatcher.ANY.precomputed());
606   }
607 }
608