1 /*
2  * Copyright (C) 2009 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.truth.Truth.assertThat;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.annotations.GwtIncompatible;
23 import com.google.common.base.Splitter.MapSplitter;
24 import com.google.common.collect.ImmutableMap;
25 import com.google.common.testing.NullPointerTester;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.regex.Pattern;
30 import junit.framework.TestCase;
31 
32 /** @author Julien Silland */
33 @GwtCompatible(emulated = true)
34 public class SplitterTest extends TestCase {
35 
36   private static final Splitter COMMA_SPLITTER = Splitter.on(',');
37 
testSplitNullString()38   public void testSplitNullString() {
39     try {
40       COMMA_SPLITTER.split(null);
41       fail();
42     } catch (NullPointerException expected) {
43     }
44   }
45 
testCharacterSimpleSplit()46   public void testCharacterSimpleSplit() {
47     String simple = "a,b,c";
48     Iterable<String> letters = COMMA_SPLITTER.split(simple);
49     assertThat(letters).containsExactly("a", "b", "c").inOrder();
50   }
51 
52   /**
53    * All of the infrastructure of split and splitToString is identical, so we do one test of
54    * splitToString. All other cases should be covered by testing of split.
55    *
56    * <p>TODO(user): It would be good to make all the relevant tests run on both split and
57    * splitToString automatically.
58    */
testCharacterSimpleSplitToList()59   public void testCharacterSimpleSplitToList() {
60     String simple = "a,b,c";
61     List<String> letters = COMMA_SPLITTER.splitToList(simple);
62     assertThat(letters).containsExactly("a", "b", "c").inOrder();
63   }
64 
testToString()65   public void testToString() {
66     assertEquals("[]", COMMA_SPLITTER.split("").toString());
67     assertEquals("[a, b, c]", COMMA_SPLITTER.split("a,b,c").toString());
68     assertEquals("[yam, bam, jam, ham]", Splitter.on(", ").split("yam, bam, jam, ham").toString());
69   }
70 
testCharacterSimpleSplitWithNoDelimiter()71   public void testCharacterSimpleSplitWithNoDelimiter() {
72     String simple = "a,b,c";
73     Iterable<String> letters = Splitter.on('.').split(simple);
74     assertThat(letters).containsExactly("a,b,c").inOrder();
75   }
76 
testCharacterSplitWithDoubleDelimiter()77   public void testCharacterSplitWithDoubleDelimiter() {
78     String doubled = "a,,b,c";
79     Iterable<String> letters = COMMA_SPLITTER.split(doubled);
80     assertThat(letters).containsExactly("a", "", "b", "c").inOrder();
81   }
82 
testCharacterSplitWithDoubleDelimiterAndSpace()83   public void testCharacterSplitWithDoubleDelimiterAndSpace() {
84     String doubled = "a,, b,c";
85     Iterable<String> letters = COMMA_SPLITTER.split(doubled);
86     assertThat(letters).containsExactly("a", "", " b", "c").inOrder();
87   }
88 
testCharacterSplitWithTrailingDelimiter()89   public void testCharacterSplitWithTrailingDelimiter() {
90     String trailing = "a,b,c,";
91     Iterable<String> letters = COMMA_SPLITTER.split(trailing);
92     assertThat(letters).containsExactly("a", "b", "c", "").inOrder();
93   }
94 
testCharacterSplitWithLeadingDelimiter()95   public void testCharacterSplitWithLeadingDelimiter() {
96     String leading = ",a,b,c";
97     Iterable<String> letters = COMMA_SPLITTER.split(leading);
98     assertThat(letters).containsExactly("", "a", "b", "c").inOrder();
99   }
100 
testCharacterSplitWithMultipleLetters()101   public void testCharacterSplitWithMultipleLetters() {
102     Iterable<String> testCharacteringMotto =
103         Splitter.on('-').split("Testing-rocks-Debugging-sucks");
104     assertThat(testCharacteringMotto)
105         .containsExactly("Testing", "rocks", "Debugging", "sucks")
106         .inOrder();
107   }
108 
testCharacterSplitWithMatcherDelimiter()109   public void testCharacterSplitWithMatcherDelimiter() {
110     Iterable<String> testCharacteringMotto =
111         Splitter.on(CharMatcher.whitespace()).split("Testing\nrocks\tDebugging sucks");
112     assertThat(testCharacteringMotto)
113         .containsExactly("Testing", "rocks", "Debugging", "sucks")
114         .inOrder();
115   }
116 
testCharacterSplitWithDoubleDelimiterOmitEmptyStrings()117   public void testCharacterSplitWithDoubleDelimiterOmitEmptyStrings() {
118     String doubled = "a..b.c";
119     Iterable<String> letters = Splitter.on('.').omitEmptyStrings().split(doubled);
120     assertThat(letters).containsExactly("a", "b", "c").inOrder();
121   }
122 
testCharacterSplitEmptyToken()123   public void testCharacterSplitEmptyToken() {
124     String emptyToken = "a. .c";
125     Iterable<String> letters = Splitter.on('.').trimResults().split(emptyToken);
126     assertThat(letters).containsExactly("a", "", "c").inOrder();
127   }
128 
testCharacterSplitEmptyTokenOmitEmptyStrings()129   public void testCharacterSplitEmptyTokenOmitEmptyStrings() {
130     String emptyToken = "a. .c";
131     Iterable<String> letters = Splitter.on('.').omitEmptyStrings().trimResults().split(emptyToken);
132     assertThat(letters).containsExactly("a", "c").inOrder();
133   }
134 
testCharacterSplitOnEmptyString()135   public void testCharacterSplitOnEmptyString() {
136     Iterable<String> nothing = Splitter.on('.').split("");
137     assertThat(nothing).containsExactly("").inOrder();
138   }
139 
testCharacterSplitOnEmptyStringOmitEmptyStrings()140   public void testCharacterSplitOnEmptyStringOmitEmptyStrings() {
141     assertThat(Splitter.on('.').omitEmptyStrings().split("")).isEmpty();
142   }
143 
testCharacterSplitOnOnlyDelimiter()144   public void testCharacterSplitOnOnlyDelimiter() {
145     Iterable<String> blankblank = Splitter.on('.').split(".");
146     assertThat(blankblank).containsExactly("", "").inOrder();
147   }
148 
testCharacterSplitOnOnlyDelimitersOmitEmptyStrings()149   public void testCharacterSplitOnOnlyDelimitersOmitEmptyStrings() {
150     Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("...");
151     assertThat(empty).isEmpty();
152   }
153 
testCharacterSplitWithTrim()154   public void testCharacterSplitWithTrim() {
155     String jacksons =
156         "arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";
157     Iterable<String> family =
158         COMMA_SPLITTER
159             .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace()))
160             .split(jacksons);
161     assertThat(family)
162         .containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)")
163         .inOrder();
164   }
165 
testStringSimpleSplit()166   public void testStringSimpleSplit() {
167     String simple = "a,b,c";
168     Iterable<String> letters = Splitter.on(",").split(simple);
169     assertThat(letters).containsExactly("a", "b", "c").inOrder();
170   }
171 
testStringSimpleSplitWithNoDelimiter()172   public void testStringSimpleSplitWithNoDelimiter() {
173     String simple = "a,b,c";
174     Iterable<String> letters = Splitter.on(".").split(simple);
175     assertThat(letters).containsExactly("a,b,c").inOrder();
176   }
177 
testStringSplitWithDoubleDelimiter()178   public void testStringSplitWithDoubleDelimiter() {
179     String doubled = "a,,b,c";
180     Iterable<String> letters = Splitter.on(",").split(doubled);
181     assertThat(letters).containsExactly("a", "", "b", "c").inOrder();
182   }
183 
testStringSplitWithDoubleDelimiterAndSpace()184   public void testStringSplitWithDoubleDelimiterAndSpace() {
185     String doubled = "a,, b,c";
186     Iterable<String> letters = Splitter.on(",").split(doubled);
187     assertThat(letters).containsExactly("a", "", " b", "c").inOrder();
188   }
189 
testStringSplitWithTrailingDelimiter()190   public void testStringSplitWithTrailingDelimiter() {
191     String trailing = "a,b,c,";
192     Iterable<String> letters = Splitter.on(",").split(trailing);
193     assertThat(letters).containsExactly("a", "b", "c", "").inOrder();
194   }
195 
testStringSplitWithLeadingDelimiter()196   public void testStringSplitWithLeadingDelimiter() {
197     String leading = ",a,b,c";
198     Iterable<String> letters = Splitter.on(",").split(leading);
199     assertThat(letters).containsExactly("", "a", "b", "c").inOrder();
200   }
201 
testStringSplitWithMultipleLetters()202   public void testStringSplitWithMultipleLetters() {
203     Iterable<String> testStringingMotto = Splitter.on("-").split("Testing-rocks-Debugging-sucks");
204     assertThat(testStringingMotto)
205         .containsExactly("Testing", "rocks", "Debugging", "sucks")
206         .inOrder();
207   }
208 
testStringSplitWithDoubleDelimiterOmitEmptyStrings()209   public void testStringSplitWithDoubleDelimiterOmitEmptyStrings() {
210     String doubled = "a..b.c";
211     Iterable<String> letters = Splitter.on(".").omitEmptyStrings().split(doubled);
212     assertThat(letters).containsExactly("a", "b", "c").inOrder();
213   }
214 
testStringSplitEmptyToken()215   public void testStringSplitEmptyToken() {
216     String emptyToken = "a. .c";
217     Iterable<String> letters = Splitter.on(".").trimResults().split(emptyToken);
218     assertThat(letters).containsExactly("a", "", "c").inOrder();
219   }
220 
testStringSplitEmptyTokenOmitEmptyStrings()221   public void testStringSplitEmptyTokenOmitEmptyStrings() {
222     String emptyToken = "a. .c";
223     Iterable<String> letters = Splitter.on(".").omitEmptyStrings().trimResults().split(emptyToken);
224     assertThat(letters).containsExactly("a", "c").inOrder();
225   }
226 
testStringSplitWithLongDelimiter()227   public void testStringSplitWithLongDelimiter() {
228     String longDelimiter = "a, b, c";
229     Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
230     assertThat(letters).containsExactly("a", "b", "c").inOrder();
231   }
232 
testStringSplitWithLongLeadingDelimiter()233   public void testStringSplitWithLongLeadingDelimiter() {
234     String longDelimiter = ", a, b, c";
235     Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
236     assertThat(letters).containsExactly("", "a", "b", "c").inOrder();
237   }
238 
testStringSplitWithLongTrailingDelimiter()239   public void testStringSplitWithLongTrailingDelimiter() {
240     String longDelimiter = "a, b, c, ";
241     Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
242     assertThat(letters).containsExactly("a", "b", "c", "").inOrder();
243   }
244 
testStringSplitWithDelimiterSubstringInValue()245   public void testStringSplitWithDelimiterSubstringInValue() {
246     String fourCommasAndFourSpaces = ",,,,    ";
247     Iterable<String> threeCommasThenThreeSpaces = Splitter.on(", ").split(fourCommasAndFourSpaces);
248     assertThat(threeCommasThenThreeSpaces).containsExactly(",,,", "   ").inOrder();
249   }
250 
testStringSplitWithEmptyString()251   public void testStringSplitWithEmptyString() {
252     try {
253       Splitter.on("");
254       fail();
255     } catch (IllegalArgumentException expected) {
256     }
257   }
258 
testStringSplitOnEmptyString()259   public void testStringSplitOnEmptyString() {
260     Iterable<String> notMuch = Splitter.on(".").split("");
261     assertThat(notMuch).containsExactly("").inOrder();
262   }
263 
testStringSplitOnEmptyStringOmitEmptyString()264   public void testStringSplitOnEmptyStringOmitEmptyString() {
265     assertThat(Splitter.on(".").omitEmptyStrings().split("")).isEmpty();
266   }
267 
testStringSplitOnOnlyDelimiter()268   public void testStringSplitOnOnlyDelimiter() {
269     Iterable<String> blankblank = Splitter.on(".").split(".");
270     assertThat(blankblank).containsExactly("", "").inOrder();
271   }
272 
testStringSplitOnOnlyDelimitersOmitEmptyStrings()273   public void testStringSplitOnOnlyDelimitersOmitEmptyStrings() {
274     Iterable<String> empty = Splitter.on(".").omitEmptyStrings().split("...");
275     assertThat(empty).isEmpty();
276   }
277 
testStringSplitWithTrim()278   public void testStringSplitWithTrim() {
279     String jacksons =
280         "arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";
281     Iterable<String> family =
282         Splitter.on(",")
283             .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace()))
284             .split(jacksons);
285     assertThat(family)
286         .containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)")
287         .inOrder();
288   }
289 
290   @GwtIncompatible // Splitter.onPattern
testPatternSimpleSplit()291   public void testPatternSimpleSplit() {
292     String simple = "a,b,c";
293     Iterable<String> letters = Splitter.onPattern(",").split(simple);
294     assertThat(letters).containsExactly("a", "b", "c").inOrder();
295   }
296 
297   @GwtIncompatible // Splitter.onPattern
testPatternSimpleSplitWithNoDelimiter()298   public void testPatternSimpleSplitWithNoDelimiter() {
299     String simple = "a,b,c";
300     Iterable<String> letters = Splitter.onPattern("foo").split(simple);
301     assertThat(letters).containsExactly("a,b,c").inOrder();
302   }
303 
304   @GwtIncompatible // Splitter.onPattern
testPatternSplitWithDoubleDelimiter()305   public void testPatternSplitWithDoubleDelimiter() {
306     String doubled = "a,,b,c";
307     Iterable<String> letters = Splitter.onPattern(",").split(doubled);
308     assertThat(letters).containsExactly("a", "", "b", "c").inOrder();
309   }
310 
311   @GwtIncompatible // Splitter.onPattern
testPatternSplitWithDoubleDelimiterAndSpace()312   public void testPatternSplitWithDoubleDelimiterAndSpace() {
313     String doubled = "a,, b,c";
314     Iterable<String> letters = Splitter.onPattern(",").split(doubled);
315     assertThat(letters).containsExactly("a", "", " b", "c").inOrder();
316   }
317 
318   @GwtIncompatible // Splitter.onPattern
testPatternSplitWithTrailingDelimiter()319   public void testPatternSplitWithTrailingDelimiter() {
320     String trailing = "a,b,c,";
321     Iterable<String> letters = Splitter.onPattern(",").split(trailing);
322     assertThat(letters).containsExactly("a", "b", "c", "").inOrder();
323   }
324 
325   @GwtIncompatible // Splitter.onPattern
testPatternSplitWithLeadingDelimiter()326   public void testPatternSplitWithLeadingDelimiter() {
327     String leading = ",a,b,c";
328     Iterable<String> letters = Splitter.onPattern(",").split(leading);
329     assertThat(letters).containsExactly("", "a", "b", "c").inOrder();
330   }
331 
332   // TODO(kevinb): the name of this method suggests it might not actually be testing what it
333   // intends to be testing?
334   @GwtIncompatible // Splitter.onPattern
testPatternSplitWithMultipleLetters()335   public void testPatternSplitWithMultipleLetters() {
336     Iterable<String> testPatterningMotto =
337         Splitter.onPattern("-").split("Testing-rocks-Debugging-sucks");
338     assertThat(testPatterningMotto)
339         .containsExactly("Testing", "rocks", "Debugging", "sucks")
340         .inOrder();
341   }
342 
343   @GwtIncompatible // java.util.regex.Pattern
literalDotPattern()344   private static Pattern literalDotPattern() {
345     return Pattern.compile("\\.");
346   }
347 
348   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWithDoubleDelimiterOmitEmptyStrings()349   public void testPatternSplitWithDoubleDelimiterOmitEmptyStrings() {
350     String doubled = "a..b.c";
351     Iterable<String> letters = Splitter.on(literalDotPattern()).omitEmptyStrings().split(doubled);
352     assertThat(letters).containsExactly("a", "b", "c").inOrder();
353   }
354 
355   @GwtIncompatible // java.util.regex.Pattern
356   @AndroidIncompatible // Bug in older versions of Android we test against, since fixed.
testPatternSplitLookBehind()357   public void testPatternSplitLookBehind() {
358     if (!CommonPattern.isPcreLike()) {
359       return;
360     }
361     String toSplit = ":foo::barbaz:";
362     String regexPattern = "(?<=:)";
363     Iterable<String> split = Splitter.onPattern(regexPattern).split(toSplit);
364     assertThat(split).containsExactly(":", "foo:", ":", "barbaz:").inOrder();
365     // splits into chunks ending in :
366   }
367 
368   @GwtIncompatible // java.util.regex.Pattern
369   @AndroidIncompatible // Bug in older versions of Android we test against, since fixed.
testPatternSplitWordBoundary()370   public void testPatternSplitWordBoundary() {
371     String string = "foo<bar>bletch";
372     Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);
373     assertThat(words).containsExactly("foo", "<", "bar", ">", "bletch").inOrder();
374   }
375 
376   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWordBoundary_singleCharInput()377   public void testPatternSplitWordBoundary_singleCharInput() {
378     String string = "f";
379     Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);
380     assertThat(words).containsExactly("f").inOrder();
381   }
382 
383   @AndroidIncompatible // Apparently Gingerbread's regex API is buggy.
384   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWordBoundary_singleWordInput()385   public void testPatternSplitWordBoundary_singleWordInput() {
386     String string = "foo";
387     Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);
388     assertThat(words).containsExactly("foo").inOrder();
389   }
390 
391   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitEmptyToken()392   public void testPatternSplitEmptyToken() {
393     String emptyToken = "a. .c";
394     Iterable<String> letters = Splitter.on(literalDotPattern()).trimResults().split(emptyToken);
395     assertThat(letters).containsExactly("a", "", "c").inOrder();
396   }
397 
398   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitEmptyTokenOmitEmptyStrings()399   public void testPatternSplitEmptyTokenOmitEmptyStrings() {
400     String emptyToken = "a. .c";
401     Iterable<String> letters =
402         Splitter.on(literalDotPattern()).omitEmptyStrings().trimResults().split(emptyToken);
403     assertThat(letters).containsExactly("a", "c").inOrder();
404   }
405 
406   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitOnOnlyDelimiter()407   public void testPatternSplitOnOnlyDelimiter() {
408     Iterable<String> blankblank = Splitter.on(literalDotPattern()).split(".");
409 
410     assertThat(blankblank).containsExactly("", "").inOrder();
411   }
412 
413   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitOnOnlyDelimitersOmitEmptyStrings()414   public void testPatternSplitOnOnlyDelimitersOmitEmptyStrings() {
415     Iterable<String> empty = Splitter.on(literalDotPattern()).omitEmptyStrings().split("...");
416     assertThat(empty).isEmpty();
417   }
418 
419   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitMatchingIsGreedy()420   public void testPatternSplitMatchingIsGreedy() {
421     String longDelimiter = "a, b,   c";
422     Iterable<String> letters = Splitter.on(Pattern.compile(",\\s*")).split(longDelimiter);
423     assertThat(letters).containsExactly("a", "b", "c").inOrder();
424   }
425 
426   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWithLongLeadingDelimiter()427   public void testPatternSplitWithLongLeadingDelimiter() {
428     String longDelimiter = ", a, b, c";
429     Iterable<String> letters = Splitter.on(Pattern.compile(", ")).split(longDelimiter);
430     assertThat(letters).containsExactly("", "a", "b", "c").inOrder();
431   }
432 
433   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWithLongTrailingDelimiter()434   public void testPatternSplitWithLongTrailingDelimiter() {
435     String longDelimiter = "a, b, c/ ";
436     Iterable<String> letters = Splitter.on(Pattern.compile("[,/]\\s")).split(longDelimiter);
437     assertThat(letters).containsExactly("a", "b", "c", "").inOrder();
438   }
439 
440   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitInvalidPattern()441   public void testPatternSplitInvalidPattern() {
442     try {
443       Splitter.on(Pattern.compile("a*"));
444       fail();
445     } catch (IllegalArgumentException expected) {
446     }
447   }
448 
449   @GwtIncompatible // java.util.regex.Pattern
testPatternSplitWithTrim()450   public void testPatternSplitWithTrim() {
451     String jacksons =
452         "arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";
453     Iterable<String> family =
454         Splitter.on(Pattern.compile(","))
455             .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace()))
456             .split(jacksons);
457     assertThat(family)
458         .containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)")
459         .inOrder();
460   }
461 
testSplitterIterableIsUnmodifiable_char()462   public void testSplitterIterableIsUnmodifiable_char() {
463     assertIteratorIsUnmodifiable(COMMA_SPLITTER.split("a,b").iterator());
464   }
465 
testSplitterIterableIsUnmodifiable_string()466   public void testSplitterIterableIsUnmodifiable_string() {
467     assertIteratorIsUnmodifiable(Splitter.on(",").split("a,b").iterator());
468   }
469 
470   @GwtIncompatible // java.util.regex.Pattern
testSplitterIterableIsUnmodifiable_pattern()471   public void testSplitterIterableIsUnmodifiable_pattern() {
472     assertIteratorIsUnmodifiable(Splitter.on(Pattern.compile(",")).split("a,b").iterator());
473   }
474 
assertIteratorIsUnmodifiable(Iterator<?> iterator)475   private void assertIteratorIsUnmodifiable(Iterator<?> iterator) {
476     iterator.next();
477     try {
478       iterator.remove();
479       fail();
480     } catch (UnsupportedOperationException expected) {
481     }
482   }
483 
testSplitterIterableIsLazy_char()484   public void testSplitterIterableIsLazy_char() {
485     assertSplitterIterableIsLazy(COMMA_SPLITTER);
486   }
487 
testSplitterIterableIsLazy_string()488   public void testSplitterIterableIsLazy_string() {
489     assertSplitterIterableIsLazy(Splitter.on(","));
490   }
491 
492   @GwtIncompatible // java.util.regex.Pattern
493   @AndroidIncompatible // not clear that j.u.r.Matcher promises to handle mutations during use
testSplitterIterableIsLazy_pattern()494   public void testSplitterIterableIsLazy_pattern() {
495     if (!CommonPattern.isPcreLike()) {
496       return;
497     }
498     assertSplitterIterableIsLazy(Splitter.onPattern(","));
499   }
500 
501   /**
502    * This test really pushes the boundaries of what we support. In general the splitter's behaviour
503    * is not well defined if the char sequence it's splitting is mutated during iteration.
504    */
assertSplitterIterableIsLazy(Splitter splitter)505   private void assertSplitterIterableIsLazy(Splitter splitter) {
506     StringBuilder builder = new StringBuilder();
507     Iterator<String> iterator = splitter.split(builder).iterator();
508 
509     builder.append("A,");
510     assertEquals("A", iterator.next());
511     builder.append("B,");
512     assertEquals("B", iterator.next());
513     builder.append("C");
514     assertEquals("C", iterator.next());
515     assertFalse(iterator.hasNext());
516   }
517 
testFixedLengthSimpleSplit()518   public void testFixedLengthSimpleSplit() {
519     String simple = "abcde";
520     Iterable<String> letters = Splitter.fixedLength(2).split(simple);
521     assertThat(letters).containsExactly("ab", "cd", "e").inOrder();
522   }
523 
testFixedLengthSplitEqualChunkLength()524   public void testFixedLengthSplitEqualChunkLength() {
525     String simple = "abcdef";
526     Iterable<String> letters = Splitter.fixedLength(2).split(simple);
527     assertThat(letters).containsExactly("ab", "cd", "ef").inOrder();
528   }
529 
testFixedLengthSplitOnlyOneChunk()530   public void testFixedLengthSplitOnlyOneChunk() {
531     String simple = "abc";
532     Iterable<String> letters = Splitter.fixedLength(3).split(simple);
533     assertThat(letters).containsExactly("abc").inOrder();
534   }
535 
testFixedLengthSplitSmallerString()536   public void testFixedLengthSplitSmallerString() {
537     String simple = "ab";
538     Iterable<String> letters = Splitter.fixedLength(3).split(simple);
539     assertThat(letters).containsExactly("ab").inOrder();
540   }
541 
testFixedLengthSplitEmptyString()542   public void testFixedLengthSplitEmptyString() {
543     String simple = "";
544     Iterable<String> letters = Splitter.fixedLength(3).split(simple);
545     assertThat(letters).containsExactly("").inOrder();
546   }
547 
testFixedLengthSplitEmptyStringWithOmitEmptyStrings()548   public void testFixedLengthSplitEmptyStringWithOmitEmptyStrings() {
549     assertThat(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty();
550   }
551 
testFixedLengthSplitIntoChars()552   public void testFixedLengthSplitIntoChars() {
553     String simple = "abcd";
554     Iterable<String> letters = Splitter.fixedLength(1).split(simple);
555     assertThat(letters).containsExactly("a", "b", "c", "d").inOrder();
556   }
557 
testFixedLengthSplitZeroChunkLen()558   public void testFixedLengthSplitZeroChunkLen() {
559     try {
560       Splitter.fixedLength(0);
561       fail();
562     } catch (IllegalArgumentException expected) {
563     }
564   }
565 
testFixedLengthSplitNegativeChunkLen()566   public void testFixedLengthSplitNegativeChunkLen() {
567     try {
568       Splitter.fixedLength(-1);
569       fail();
570     } catch (IllegalArgumentException expected) {
571     }
572   }
573 
testLimitLarge()574   public void testLimitLarge() {
575     String simple = "abcd";
576     Iterable<String> letters = Splitter.fixedLength(1).limit(100).split(simple);
577     assertThat(letters).containsExactly("a", "b", "c", "d").inOrder();
578   }
579 
testLimitOne()580   public void testLimitOne() {
581     String simple = "abcd";
582     Iterable<String> letters = Splitter.fixedLength(1).limit(1).split(simple);
583     assertThat(letters).containsExactly("abcd").inOrder();
584   }
585 
testLimitFixedLength()586   public void testLimitFixedLength() {
587     String simple = "abcd";
588     Iterable<String> letters = Splitter.fixedLength(1).limit(2).split(simple);
589     assertThat(letters).containsExactly("a", "bcd").inOrder();
590   }
591 
testLimit1Separator()592   public void testLimit1Separator() {
593     String simple = "a,b,c,d";
594     Iterable<String> items = COMMA_SPLITTER.limit(1).split(simple);
595     assertThat(items).containsExactly("a,b,c,d").inOrder();
596   }
597 
testLimitSeparator()598   public void testLimitSeparator() {
599     String simple = "a,b,c,d";
600     Iterable<String> items = COMMA_SPLITTER.limit(2).split(simple);
601     assertThat(items).containsExactly("a", "b,c,d").inOrder();
602   }
603 
testLimitExtraSeparators()604   public void testLimitExtraSeparators() {
605     String text = "a,,,b,,c,d";
606     Iterable<String> items = COMMA_SPLITTER.limit(2).split(text);
607     assertThat(items).containsExactly("a", ",,b,,c,d").inOrder();
608   }
609 
testLimitExtraSeparatorsOmitEmpty()610   public void testLimitExtraSeparatorsOmitEmpty() {
611     String text = "a,,,b,,c,d";
612     Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().split(text);
613     assertThat(items).containsExactly("a", "b,,c,d").inOrder();
614   }
615 
testLimitExtraSeparatorsOmitEmpty3()616   public void testLimitExtraSeparatorsOmitEmpty3() {
617     String text = "a,,,b,,c,d";
618     Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().split(text);
619     assertThat(items).containsExactly("a", "b", "c,d").inOrder();
620   }
621 
testLimitExtraSeparatorsTrim()622   public void testLimitExtraSeparatorsTrim() {
623     String text = ",,a,,  , b ,, c,d ";
624     Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().trimResults().split(text);
625     assertThat(items).containsExactly("a", "b ,, c,d").inOrder();
626   }
627 
testLimitExtraSeparatorsTrim3()628   public void testLimitExtraSeparatorsTrim3() {
629     String text = ",,a,,  , b ,, c,d ";
630     Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().trimResults().split(text);
631     assertThat(items).containsExactly("a", "b", "c,d").inOrder();
632   }
633 
testLimitExtraSeparatorsTrim1()634   public void testLimitExtraSeparatorsTrim1() {
635     String text = ",,a,,  , b ,, c,d ";
636     Iterable<String> items = COMMA_SPLITTER.limit(1).omitEmptyStrings().trimResults().split(text);
637     assertThat(items).containsExactly("a,,  , b ,, c,d").inOrder();
638   }
639 
testLimitExtraSeparatorsTrim1NoOmit()640   public void testLimitExtraSeparatorsTrim1NoOmit() {
641     String text = ",,a,,  , b ,, c,d ";
642     Iterable<String> items = COMMA_SPLITTER.limit(1).trimResults().split(text);
643     assertThat(items).containsExactly(",,a,,  , b ,, c,d").inOrder();
644   }
645 
testLimitExtraSeparatorsTrim1Empty()646   public void testLimitExtraSeparatorsTrim1Empty() {
647     String text = "";
648     Iterable<String> items = COMMA_SPLITTER.limit(1).split(text);
649     assertThat(items).containsExactly("").inOrder();
650   }
651 
testLimitExtraSeparatorsTrim1EmptyOmit()652   public void testLimitExtraSeparatorsTrim1EmptyOmit() {
653     String text = "";
654     Iterable<String> items = COMMA_SPLITTER.omitEmptyStrings().limit(1).split(text);
655     assertThat(items).isEmpty();
656   }
657 
testInvalidZeroLimit()658   public void testInvalidZeroLimit() {
659     try {
660       COMMA_SPLITTER.limit(0);
661       fail();
662     } catch (IllegalArgumentException expected) {
663     }
664   }
665 
666   @GwtIncompatible // NullPointerTester
testNullPointers()667   public void testNullPointers() {
668     NullPointerTester tester = new NullPointerTester();
669     tester.testAllPublicStaticMethods(Splitter.class);
670     tester.testAllPublicInstanceMethods(COMMA_SPLITTER);
671     tester.testAllPublicInstanceMethods(COMMA_SPLITTER.trimResults());
672   }
673 
testMapSplitter_trimmedBoth()674   public void testMapSplitter_trimmedBoth() {
675     Map<String, String> m =
676         COMMA_SPLITTER
677             .trimResults()
678             .withKeyValueSeparator(Splitter.on(':').trimResults())
679             .split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");
680     ImmutableMap<String, String> expected =
681         ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
682     assertThat(m).isEqualTo(expected);
683     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
684   }
685 
testMapSplitter_trimmedEntries()686   public void testMapSplitter_trimmedEntries() {
687     Map<String, String> m =
688         COMMA_SPLITTER
689             .trimResults()
690             .withKeyValueSeparator(":")
691             .split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");
692     ImmutableMap<String, String> expected =
693         ImmutableMap.of("boy  ", " tom", "girl", " tina", "cat  ", " kitty", "dog", " tommy");
694 
695     assertThat(m).isEqualTo(expected);
696     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
697   }
698 
testMapSplitter_trimmedKeyValue()699   public void testMapSplitter_trimmedKeyValue() {
700     Map<String, String> m =
701         COMMA_SPLITTER
702             .withKeyValueSeparator(Splitter.on(':').trimResults())
703             .split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");
704     ImmutableMap<String, String> expected =
705         ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
706     assertThat(m).isEqualTo(expected);
707     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
708   }
709 
testMapSplitter_notTrimmed()710   public void testMapSplitter_notTrimmed() {
711     Map<String, String> m =
712         COMMA_SPLITTER
713             .withKeyValueSeparator(":")
714             .split(" boy:tom , girl: tina , cat :kitty , dog:  tommy ");
715     ImmutableMap<String, String> expected =
716         ImmutableMap.of(" boy", "tom ", " girl", " tina ", " cat ", "kitty ", " dog", "  tommy ");
717     assertThat(m).isEqualTo(expected);
718     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
719   }
720 
testMapSplitter_CharacterSeparator()721   public void testMapSplitter_CharacterSeparator() {
722     // try different delimiters.
723     Map<String, String> m =
724         Splitter.on(",").withKeyValueSeparator(':').split("boy:tom,girl:tina,cat:kitty,dog:tommy");
725     ImmutableMap<String, String> expected =
726         ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
727 
728     assertThat(m).isEqualTo(expected);
729     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
730   }
731 
testMapSplitter_multiCharacterSeparator()732   public void testMapSplitter_multiCharacterSeparator() {
733     // try different delimiters.
734     Map<String, String> m =
735         Splitter.on(",")
736             .withKeyValueSeparator(":^&")
737             .split("boy:^&tom,girl:^&tina,cat:^&kitty,dog:^&tommy");
738     ImmutableMap<String, String> expected =
739         ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
740 
741     assertThat(m).isEqualTo(expected);
742     assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();
743   }
744 
testMapSplitter_emptySeparator()745   public void testMapSplitter_emptySeparator() {
746     try {
747       COMMA_SPLITTER.withKeyValueSeparator("");
748       fail();
749     } catch (IllegalArgumentException expected) {
750     }
751   }
752 
testMapSplitter_malformedEntry()753   public void testMapSplitter_malformedEntry() {
754     try {
755       COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,b,c=2");
756       fail();
757     } catch (IllegalArgumentException expected) {
758     }
759   }
760 
761   /**
762    * Testing the behavior in https://github.com/google/guava/issues/1900 - this behavior may want to
763    * be changed?
764    */
testMapSplitter_extraValueDelimiter()765   public void testMapSplitter_extraValueDelimiter() {
766     try {
767       COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,c=2=");
768       fail();
769     } catch (IllegalArgumentException expected) {
770     }
771   }
772 
testMapSplitter_orderedResults()773   public void testMapSplitter_orderedResults() {
774     Map<String, String> m =
775         COMMA_SPLITTER.withKeyValueSeparator(":").split("boy:tom,girl:tina,cat:kitty,dog:tommy");
776 
777     assertThat(m.keySet()).containsExactly("boy", "girl", "cat", "dog").inOrder();
778     assertThat(m)
779         .isEqualTo(ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
780 
781     // try in a different order
782     m = COMMA_SPLITTER.withKeyValueSeparator(":").split("girl:tina,boy:tom,dog:tommy,cat:kitty");
783 
784     assertThat(m.keySet()).containsExactly("girl", "boy", "dog", "cat").inOrder();
785     assertThat(m)
786         .isEqualTo(ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
787   }
788 
testMapSplitter_duplicateKeys()789   public void testMapSplitter_duplicateKeys() {
790     try {
791       COMMA_SPLITTER.withKeyValueSeparator(":").split("a:1,b:2,a:3");
792       fail();
793     } catch (IllegalArgumentException expected) {
794     }
795   }
796 
testMapSplitter_varyingTrimLevels()797   public void testMapSplitter_varyingTrimLevels() {
798     MapSplitter splitter = COMMA_SPLITTER.trimResults().withKeyValueSeparator(Splitter.on("->"));
799     Map<String, String> split = splitter.split(" x -> y, z-> a ");
800     assertThat(split).containsEntry("x ", " y");
801     assertThat(split).containsEntry("z", " a");
802   }
803 }
804