10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/*
20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Copyright (C) 2008 The Guava Authors
30888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * you may not use this file except in compliance with the License.
60888a09821a98ac0680fad765217302858e70fa4Paul Duffin * You may obtain a copy of the License at
70888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
80888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
90888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software
110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * See the License for the specific language governing permissions and
140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * limitations under the License.
150888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
170888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage com.google.common.base;
180888a09821a98ac0680fad765217302858e70fa4Paul Duffin
190888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.annotations.GwtCompatible;
200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.base.Joiner.MapJoiner;
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.ImmutableMap;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.ImmutableMultimap;
230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.ImmutableSet;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.Lists;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.Maps;
260888a09821a98ac0680fad765217302858e70fa4Paul Duffin
270888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.AssertionFailedError;
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestCase;
290888a09821a98ac0680fad765217302858e70fa4Paul Duffin
300888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.io.IOException;
310888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Arrays;
320888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Iterator;
330888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Map;
340888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Set;
350888a09821a98ac0680fad765217302858e70fa4Paul Duffin
360888a09821a98ac0680fad765217302858e70fa4Paul Duffin/**
370888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unit test for {@link Joiner}.
380888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
390888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Kevin Bourrillion
400888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
410888a09821a98ac0680fad765217302858e70fa4Paul Duffin@GwtCompatible(emulated = true)
420888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic class JoinerTest extends TestCase {
430888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Joiner J = Joiner.on("-");
440888a09821a98ac0680fad765217302858e70fa4Paul Duffin
450888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // <Integer> needed to prevent warning :(
460888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_ = Arrays.<Integer>asList();
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_1 = Arrays.asList(1);
480888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_12 = Arrays.asList(1, 2);
490888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_123 = Arrays.asList(1, 2, 3);
500888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_NULL = Arrays.asList((Integer) null);
510888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_NULL_NULL
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = Arrays.asList((Integer) null, null);
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_NULL_1 = Arrays.asList(null, 1);
540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_1_NULL = Arrays.asList(1, null);
550888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_1_NULL_2 = Arrays.asList(1, null, 2);
560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Iterable<Integer> ITERABLE_FOUR_NULLS
570888a09821a98ac0680fad765217302858e70fa4Paul Duffin      = Arrays.asList((Integer) null, null, null, null);
580888a09821a98ac0680fad765217302858e70fa4Paul Duffin
590888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testNoSpecialNullBehavior() {
600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(J, ITERABLE_);
610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(J, ITERABLE_1, "1");
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(J, ITERABLE_12, "1-2");
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(J, ITERABLE_123, "1-2-3");
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin      J.join(ITERABLE_NULL);
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      J.join(ITERABLE_1_NULL_2);
720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
750888a09821a98ac0680fad765217302858e70fa4Paul Duffin
760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin      J.join(ITERABLE_NULL.iterator());
780888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
820888a09821a98ac0680fad765217302858e70fa4Paul Duffin      J.join(ITERABLE_1_NULL_2.iterator());
830888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testOnCharOverride() {
890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner onChar = Joiner.on('-');
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(onChar, ITERABLE_);
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(onChar, ITERABLE_1, "1");
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(onChar, ITERABLE_12, "1-2");
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(onChar, ITERABLE_123, "1-2-3");
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
950888a09821a98ac0680fad765217302858e70fa4Paul Duffin
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testSkipNulls() {
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner skipNulls = J.skipNulls();
980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(skipNulls, ITERABLE_);
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(skipNulls, ITERABLE_NULL);
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(skipNulls, ITERABLE_NULL_NULL);
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(skipNulls, ITERABLE_FOUR_NULLS);
1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_1, "1");
1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_12, "1-2");
1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_123, "1-2-3");
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_NULL_1, "1");
1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_1_NULL, "1");
1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(skipNulls, ITERABLE_1_NULL_2, "1-2");
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testUseForNull() {
1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner zeroForNull = J.useForNull("0");
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNoOutput(zeroForNull, ITERABLE_);
1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_1, "1");
1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_12, "1-2");
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_123, "1-2-3");
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_NULL, "0");
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_NULL_NULL, "0-0");
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_NULL_1, "0-1");
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_1_NULL, "1-0");
1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_1_NULL_2, "1-0-2");
1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkResult(zeroForNull, ITERABLE_FOUR_NULLS, "0-0-0-0");
1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static void checkNoOutput(Joiner joiner, Iterable<Integer> set) {
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", joiner.join(set));
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", joiner.join(set.iterator()));
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Object[] array = Lists.newArrayList(set).toArray(new Integer[0]);
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", joiner.join(array));
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb1FromIterable = new StringBuilder();
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(sb1FromIterable, joiner.appendTo(sb1FromIterable, set));
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, sb1FromIterable.length());
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb1FromIterator = new StringBuilder();
1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(sb1FromIterator, joiner.appendTo(sb1FromIterator, set));
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, sb1FromIterator.length());
1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb2 = new StringBuilder();
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertSame(sb2, joiner.appendTo(sb2, array));
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(0, sb2.length());
1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin      joiner.appendTo(NASTY_APPENDABLE, set);
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IOException e) {
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionError(e);
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin      joiner.appendTo(NASTY_APPENDABLE, set.iterator());
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IOException e) {
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionError(e);
1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin      joiner.appendTo(NASTY_APPENDABLE, array);
1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (IOException e) {
1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionError(e);
1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Appendable NASTY_APPENDABLE = new Appendable() {
1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Appendable append(CharSequence csq) throws IOException {
1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new IOException();
1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Appendable append(CharSequence csq, int start, int end) throws IOException {
1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new IOException();
1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Appendable append(char c) throws IOException {
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new IOException();
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin  };
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static void checkResult(Joiner joiner, Iterable<Integer> parts, String expected) {
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, joiner.join(parts));
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, joiner.join(parts.iterator()));
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb1FromIterable = new StringBuilder().append('x');
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    joiner.appendTo(sb1FromIterable, parts);
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("x" + expected, sb1FromIterable.toString());
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb1FromIterator = new StringBuilder().append('x');
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    joiner.appendTo(sb1FromIterator, parts.iterator());
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("x" + expected, sb1FromIterator.toString());
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Integer[] partsArray = Lists.newArrayList(parts).toArray(new Integer[0]);
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(expected, joiner.join(partsArray));
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb2 = new StringBuilder().append('x');
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    joiner.appendTo(sb2, partsArray);
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("x" + expected, sb2.toString());
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int num = partsArray.length - 2;
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (num >= 0) {
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Object[] rest = new Integer[num];
1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < num; i++) {
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin        rest[i] = partsArray[i + 2];
2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals(expected, joiner.join(partsArray[0], partsArray[1], rest));
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      StringBuilder sb3 = new StringBuilder().append('x');
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      joiner.appendTo(sb3, partsArray[0], partsArray[1], rest);
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      assertEquals("x" + expected, sb3.toString());
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void test_useForNull_skipNulls() {
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner j = Joiner.on("x").useForNull("y");
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j = j.skipNulls();
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void test_skipNulls_useForNull() {
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner j = Joiner.on("x").skipNulls();
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j = j.useForNull("y");
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void test_useForNull_twice() {
2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner j = Joiner.on("x").useForNull("y");
2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j = j.useForNull("y");
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testMap() {
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    MapJoiner j = Joiner.on(";").withKeyValueSeparator(":");
2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", j.join(ImmutableMap.of()));
2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(":", j.join(ImmutableMap.of("", "")));
2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<String, String> mapWithNulls = Maps.newLinkedHashMap();
2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    mapWithNulls.put("a", null);
2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    mapWithNulls.put(null, "b");
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j.join(mapWithNulls);
2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2520888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("a:00;00:b", j.useForNull("00").join(mapWithNulls));
2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb = new StringBuilder();
2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    j.appendTo(sb, ImmutableMap.of(1, 2, 3, 4, 5, 6));
2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("1:2;3:4;5:6", sb.toString());
2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void testEntries() {
2610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    MapJoiner j = Joiner.on(";").withKeyValueSeparator(":");
2620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", j.join(ImmutableMultimap.of().entries()));
2630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("", j.join(ImmutableMultimap.of().entries().iterator()));
2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(":", j.join(ImmutableMultimap.of("", "").entries()));
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals(":", j.join(ImmutableMultimap.of("", "").entries().iterator()));
2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("1:a;1:b", j.join(ImmutableMultimap.of("1", "a", "1", "b").entries()));
2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("1:a;1:b", j.join(ImmutableMultimap.of("1", "a", "1", "b").entries().iterator()));
2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Map<String, String> mapWithNulls = Maps.newLinkedHashMap();
2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    mapWithNulls.put("a", null);
2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    mapWithNulls.put(null, "b");
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Map.Entry<String, String>> entriesWithNulls = mapWithNulls.entrySet();
2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j.join(entriesWithNulls);
2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
2780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j.join(entriesWithNulls.iterator());
2820888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (NullPointerException expected) {
2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("a:00;00:b", j.useForNull("00").join(entriesWithNulls));
2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("a:00;00:b", j.useForNull("00").join(entriesWithNulls.iterator()));
2880888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb1 = new StringBuilder();
2900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    j.appendTo(sb1, ImmutableMultimap.of(1, 2, 3, 4, 5, 6, 1, 3, 5, 10).entries());
2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("1:2;1:3;3:4;5:6;5:10", sb1.toString());
2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    StringBuilder sb2 = new StringBuilder();
2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    j.appendTo(sb2, ImmutableMultimap.of(1, 2, 3, 4, 5, 6, 1, 3, 5, 10).entries().iterator());
2950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    assertEquals("1:2;1:3;3:4;5:6;5:10", sb2.toString());
2960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2970888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @SuppressWarnings("ReturnValueIgnored") // testing for exception
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void test_skipNulls_onMap() {
3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Joiner j = Joiner.on(",").skipNulls();
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin      j.withKeyValueSeparator("/");
3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin      fail();
3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } catch (UnsupportedOperationException expected) {
3050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3070888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static class DontStringMeBro implements CharSequence {
3090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int length() {
3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return 3;
3120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public char charAt(int index) {
3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return "foo".charAt(index);
3160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public CharSequence subSequence(int start, int end) {
3190888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return "foo".subSequence(start, end);
3200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public String toString() {
3220888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionFailedError("shouldn't be invoked");
3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3260888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // Don't do this.
3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static class IterableIterator implements Iterable<Integer>, Iterator<Integer> {
3280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static final ImmutableSet<Integer> INTEGERS = ImmutableSet.of(1, 2, 3, 4);
3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private final Iterator<Integer> iterator;
3300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public IterableIterator() {
3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      this.iterator = iterator();
3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Iterator<Integer> iterator() {
3340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return INTEGERS.iterator();
3350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public boolean hasNext() {
3370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return iterator.hasNext();
3380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Integer next() {
3400888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return iterator.next();
3410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public void remove() {
3430888a09821a98ac0680fad765217302858e70fa4Paul Duffin      iterator.remove();
3440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
3450888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
3460888a09821a98ac0680fad765217302858e70fa4Paul Duffin}
3470888a09821a98ac0680fad765217302858e70fa4Paul Duffin
348