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