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