1 /*
   2  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 /**
  24  * @test
  25  * @bug 5015163 7175206 7172553
  26  * @summary test String merge/join that is the inverse of String.split()
  27  * @summary test A utility class that forms the basis of a String.join()
  28  * operation
  29  * @summary test StringJoiner subsequence on suffix always returns complete
  30  * suffix instead of requested subsequence
  31  * @run testng test.java.util.StringJoinerTest
  32  * @author Jim Gish
  33  */
  34 package test.java.util;
  35 
  36 import java.util.StringJoiner;
  37 import java.util.ArrayList;
  38 import java.util.Iterator;
  39 import org.testng.annotations.Test;
  40 import static org.testng.Assert.assertEquals;
  41 
  42 @Test(groups = {"unit","string","util","libs"})
  43 public class StringJoinerTest {
  44 
  45     private static final String EMPTY = "EMPTY";
  46     private static final String ONE = "One";
  47     private static final int ONE_LEN = ONE.length();
  48     private static final String TWO = "Two";
  49     private static final int TWO_LEN = TWO.length();
  50     private static final String THREE = "Three";
  51     private static final String FOUR = "Four";
  52     private static final String FIVE = "Five";
  53     private static final String DASH = "-";
  54 
  55     /* Uncomment when we have streams
  56     public void addAddAll() {
  57         StringJoiner sj = new StringJoiner(DASH, "{", "}");
  58         sj.add(ONE);
  59 
  60         ArrayList<String> nextOne = new ArrayList<>();
  61         nextOne.add(TWO);
  62         nextOne.add(THREE);
  63         nextOne.stream().forEach(sj::add);
  64 
  65         String expected = "{"+ONE+DASH+TWO+DASH+THREE+"}";
  66         assertEquals(sj.toString(), expected);
  67     }
  68 
  69     void addAlladd() {
  70         StringJoiner sj = new StringJoiner(DASH, "{", "}");
  71 
  72         ArrayList<String> firstOne = new ArrayList<>();
  73         firstOne.add(ONE);
  74         firstOne.add(TWO);
  75         firstOne.stream().forEach(sj::add);
  76 
  77         sj.add(THREE);
  78 
  79         String expected = "{"+ONE+DASH+TWO+DASH+THREE+"}";
  80         assertEquals(sj.toString(), expected);
  81     }
  82 
  83     // The following tests do two successive adds of different types
  84     public void addAlladdAll() {
  85         StringJoiner sj = new StringJoiner(DASH, "{", "}");
  86         ArrayList<String> firstOne = new ArrayList<>();
  87         firstOne.add(ONE);
  88         firstOne.add(TWO);
  89         firstOne.add(THREE);
  90         firstOne.stream().forEach(sj::add);
  91 
  92         ArrayList<String> nextOne = new ArrayList<>();
  93         nextOne.add(FOUR);
  94         nextOne.add(FIVE);
  95         nextOne.stream().forEach(sj::add);
  96 
  97         String expected = "{"+ONE+DASH+TWO+DASH+THREE+DASH+FOUR+DASH+FIVE+"}";
  98         assertEquals(sj.toString(), expected);
  99     }
 100 
 101     public void testInto() {
 102         ArrayList<String> list = new ArrayList<>();
 103         list.add(ONE);
 104         list.add(TWO);
 105         list.add(THREE);
 106 
 107         StringJoiner target = new StringJoiner(",", "{", "}");
 108         assertEquals(target.toString(), "{" + ONE + "," + TWO + "," + THREE + "}");
 109     }
 110     */
 111 
 112     public void addCharSequence() {
 113         StringJoiner sj = new StringJoiner(",");
 114         CharSequence cs_one = ONE;
 115         CharSequence cs_two = TWO;
 116 
 117         sj.add(cs_one);
 118         sj.add(cs_two);
 119 
 120         assertEquals(sj.toString(), ONE + "," + TWO);
 121 
 122         sj = new StringJoiner(DASH, "{", "}");
 123         sj.add(cs_one);
 124         sj.add(cs_two);
 125 
 126         assertEquals(sj.toString(), "{" + ONE + DASH + TWO + "}");
 127 
 128         StringBuilder builder = new StringBuilder(ONE);
 129         StringBuffer buffer = new StringBuffer(THREE);
 130         sj = new StringJoiner(", ", "{ ", " }");
 131         sj.add(builder).add(buffer);
 132         builder.append(TWO);
 133         buffer.append(FOUR);
 134         assertEquals(sj.toString(), "{ " + ONE + ", " + THREE + " }", "CharSequence is copied when add");
 135         sj.add(builder);
 136         assertEquals(sj.toString(), "{ " + ONE + ", " + THREE + ", " + ONE + TWO + " }");
 137     }
 138 
 139     public void addCharSequenceWithEmptyOutput() {
 140         StringJoiner sj = new StringJoiner(",").setEmptyOutput(EMPTY);
 141         CharSequence cs_one = ONE;
 142         CharSequence cs_two = TWO;
 143 
 144         sj.add(cs_one);
 145         sj.add(cs_two);
 146 
 147         assertEquals(sj.toString(), ONE + "," + TWO);
 148 
 149         sj = new StringJoiner(DASH, "{", "}");
 150         sj.add(cs_one);
 151         sj.add(cs_two);
 152         assertEquals(sj.toString(), "{" + ONE + DASH + TWO + "}");
 153 
 154         sj = new StringJoiner(DASH, "{", "}");
 155         assertEquals(sj.toString(), "{}");
 156 
 157         sj = new StringJoiner("=", "{", "}").setEmptyOutput("");
 158         assertEquals(sj.toString(), "");
 159 
 160         sj = new StringJoiner(DASH, "{", "}").setEmptyOutput(EMPTY);
 161         assertEquals(sj.toString(), EMPTY);
 162 
 163         sj.add(cs_one);
 164         sj.add(cs_two);
 165         assertEquals(sj.toString(), "{" + ONE + DASH + TWO + "}");
 166     }
 167 
 168     public void addString() {
 169         StringJoiner sj = new StringJoiner(DASH);
 170         sj.add(ONE);
 171         assertEquals(sj.toString(), ONE);
 172 
 173         sj = new StringJoiner(DASH, "{", "}");
 174         sj.add(ONE);
 175         assertEquals(sj.toString(), "{" + ONE + "}");
 176 
 177         sj.add(TWO);
 178         assertEquals(sj.toString(), "{" + ONE + DASH + TWO + "}");
 179     }
 180 
 181     public void lengthWithCustomEmptyOutput() {
 182         StringJoiner sj = new StringJoiner(DASH, "<", ">").setEmptyOutput(EMPTY);
 183         assertEquals(sj.length(), EMPTY.length());
 184         sj.add("");
 185         assertEquals(sj.length(), "<>".length());
 186         sj.add("");
 187         assertEquals(sj.length(), "<->".length());
 188         sj.add(ONE);
 189         assertEquals(sj.length(), 4 + ONE_LEN);
 190         assertEquals(sj.toString().length(), sj.length());
 191         sj.add(TWO);
 192         assertEquals(sj.length(), 5 + ONE_LEN + TWO_LEN);
 193         assertEquals(sj.toString().length(), sj.length());
 194         sj = new StringJoiner("||", "<", "-->");
 195         assertEquals(sj.length(), 4);
 196         assertEquals(sj.toString().length(), sj.length());
 197         sj.add("abcdef");
 198         assertEquals(sj.length(), 10);
 199         assertEquals(sj.toString().length(), sj.length());
 200         sj.add("xyz");
 201         assertEquals(sj.length(), 15);
 202         assertEquals(sj.toString().length(), sj.length());
 203     }
 204 
 205     public void noAddAndEmptyOutput() {
 206         StringJoiner sj = new StringJoiner(DASH, "", "").setEmptyOutput(EMPTY);
 207         assertEquals(sj.toString(), EMPTY);
 208 
 209         sj = new StringJoiner(DASH, "<..", "");
 210         assertEquals(sj.toString(), "<..");
 211 
 212         sj = new StringJoiner(DASH, "<..", "");
 213         assertEquals(sj.toString(), "<..");
 214 
 215         sj = new StringJoiner(DASH, "", "==>");
 216         assertEquals(sj.toString(), "==>");
 217 
 218         sj = new StringJoiner(DASH, "{", "}");
 219         assertEquals(sj.toString(), "{}");
 220     }
 221 
 222     @Test(expectedExceptions = {NullPointerException.class})
 223     public void setEmptyOutputNull() {
 224         new StringJoiner(DASH, "{", "}").setEmptyOutput(null);
 225     }
 226 
 227     public void stringFromtoString() {
 228         StringJoiner sj = new StringJoiner(", ");
 229         assertEquals(sj.toString(), "");
 230         sj = new StringJoiner(",", "{", "}");
 231         assertEquals(sj.toString(), "{}");
 232 
 233         sj = new StringJoiner(",");
 234         sj.add(ONE);
 235         assertEquals(sj.toString(), ONE);
 236 
 237         sj.add(TWO);
 238         assertEquals(sj.toString(), ONE + "," + TWO);
 239 
 240         sj = new StringJoiner(",", "{--", "--}");
 241         sj.add(ONE);
 242         sj.add(TWO);
 243         assertEquals(sj.toString(), "{--" + ONE + "," + TWO + "--}");
 244 
 245     }
 246 
 247     public void stringFromtoStringWithEmptyOutput() {
 248         StringJoiner sj = new StringJoiner(" ", "", "");
 249         assertEquals(sj.toString(), "");
 250         sj = new StringJoiner(", ");
 251         assertEquals(sj.toString(), "");
 252         sj = new StringJoiner(",", "{", "}");
 253         assertEquals(sj.toString(), "{}");
 254 
 255         sj = new StringJoiner(",", "{", "}").setEmptyOutput("");
 256         assertEquals(sj.toString(), "");
 257 
 258         sj = new StringJoiner(",");
 259         sj.add(ONE);
 260         assertEquals(sj.toString(), ONE);
 261 
 262         sj.add(TWO);
 263         assertEquals(sj.toString(), ONE + "," + TWO);
 264 
 265         sj = new StringJoiner(",", "{--", "--}");
 266         sj.add(ONE);
 267         sj.add(TWO);
 268         assertEquals(sj.toString(), "{--" + ONE + "," + TWO + "--}");
 269 
 270     }
 271 
 272     public void toStringWithCustomEmptyOutput() {
 273         StringJoiner sj = new StringJoiner(DASH, "<", ">").setEmptyOutput(EMPTY);
 274         assertEquals(sj.toString(), EMPTY);
 275         sj.add("");
 276         assertEquals(sj.toString(), "<>");
 277         sj.add("");
 278         assertEquals(sj.toString(), "<->");
 279     }
 280 
 281     private void testCombos(String infix, String prefix, String suffix) {
 282         StringJoiner sj = new StringJoiner(infix, prefix, suffix);
 283         assertEquals(sj.toString(), prefix + suffix);
 284         assertEquals(sj.toString().length(), sj.length());
 285         // EmptyOutput
 286         sj = new StringJoiner(infix, prefix, suffix).setEmptyOutput("<NONE>");
 287         assertEquals(sj.toString(), "<NONE>");
 288         assertEquals(sj.toString().length(), sj.length());
 289 
 290         // empty in front
 291         sj.add("");
 292         assertEquals(sj.toString(), prefix + suffix);
 293         // empty in middle
 294         sj.add("");
 295         assertEquals(sj.toString(), prefix + infix + suffix);
 296         sj.add("1");
 297         assertEquals(sj.toString(), prefix + infix + infix + "1" + suffix);
 298         // empty at end
 299         sj.add("");
 300         assertEquals(sj.toString(), prefix + infix + infix + "1" + infix + suffix);
 301 
 302         sj = new StringJoiner(infix, prefix, suffix).setEmptyOutput("<NONE>");
 303         sj.add("1");
 304         assertEquals(sj.toString(), prefix + "1" + suffix);
 305         sj.add("2");
 306         assertEquals(sj.toString(), prefix + "1" + infix + "2" + suffix);
 307         sj.add("");
 308         assertEquals(sj.toString(), prefix + "1" + infix + "2" +infix + suffix);
 309         sj.add("3");
 310         assertEquals(sj.toString(), prefix + "1" + infix + "2" +infix + infix + "3" + suffix);
 311     }
 312 
 313     public void testDelimiterCombinations() {
 314         testCombos("", "", "");
 315         testCombos("", "<", "");
 316         testCombos("", "", ">");
 317         testCombos("", "<", ">");
 318         testCombos(",", "", "");
 319         testCombos(",", "<", "");
 320         testCombos(",", "", ">");
 321         testCombos(",", "<", ">");
 322     }
 323 }
 324