1 /*
   2  * Copyright (c) 2016, 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 /*
  25  * @test
  26  * @summary Basic tests CSV printing and parsing
  27  * @modules jdk.jdeps/com.sun.tools.jdeprscan
  28  * @build TestCSV
  29  * @run testng jdk.jdeprscan.TestCSV
  30  */
  31 
  32 package jdk.jdeprscan;
  33 
  34 import java.io.ByteArrayOutputStream;
  35 import java.io.PrintStream;
  36 import java.io.UnsupportedEncodingException;
  37 
  38 import java.util.List;
  39 import org.testng.annotations.BeforeMethod;
  40 import org.testng.annotations.DataProvider;
  41 import org.testng.annotations.Test;
  42 
  43 import static org.testng.Assert.assertEquals;
  44 import static org.testng.Assert.assertTrue;
  45 
  46 import com.sun.tools.jdeprscan.CSV;
  47 import com.sun.tools.jdeprscan.CSVParseException;
  48 
  49 @Test
  50 public class TestCSV {
  51     static String NL = System.lineSeparator();
  52     ByteArrayOutputStream baos;
  53     PrintStream out;
  54 
  55     @BeforeMethod
  56     public void setup() throws UnsupportedEncodingException {
  57         baos = new ByteArrayOutputStream();
  58         out = new PrintStream(baos, true, "UTF-8");
  59     }
  60 
  61     String result() {
  62         out.flush();
  63         return new String(baos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8);
  64     }
  65 
  66     /**
  67      * Asserts string equality after checking for and removing a trailing line separator.
  68      *
  69      * @param expected expected result
  70      */
  71     void checkString(String expected) {
  72         String actual = result();
  73         assertTrue(actual.endsWith(NL));
  74         assertEquals(actual.substring(0, actual.length() - NL.length()), expected);
  75     }
  76 
  77     @DataProvider(name = "csvdata")
  78     public Object[][] getCSVData() {
  79         return new Object[][] {
  80             { "",               List.of("") },
  81             { "a",              List.of("a") },
  82             { "a,b",            List.of("a", "b") },
  83             { "a,b,c",          List.of("a", "b", "c") },
  84             { ",a,b",           List.of("", "a", "b") },
  85             { "a,b,",           List.of("a", "b", "") },
  86             { ",a,b,",          List.of("", "a", "b", "") },
  87             { ",a,,b,",         List.of("", "a", "", "b", "") },
  88             { ",",              List.of("", "") },
  89             { ",,",             List.of("", "", "") },
  90             { ",,,",            List.of("", "", "", "") },
  91             { " a , b ",        List.of(" a ", " b ") },
  92             { "a,\",\",b",      List.of("a", ",", "b") },
  93             { "a,\"b\"\"c\",d", List.of("a", "b\"c", "d") },
  94             { "a,\"b,c\",d",    List.of("a", "b,c", "d") },
  95 
  96             // from https://en.wikipedia.org/wiki/Comma-separated_values
  97             // slightly modified to enable round-tripping
  98 
  99             { "Year,Make,Model,Description,Price",
 100                 List.of("Year", "Make", "Model", "Description", "Price") },
 101             { "1997,Ford,E350,\"ac, abs, moon\",3000.00",
 102                 List.of("1997", "Ford", "E350", "ac, abs, moon", "3000.00") },
 103             { "1999,Chevy,\"Venture \"\"Extended Edition\"\"\",,4900.00",
 104                 List.of("1999", "Chevy", "Venture \"Extended Edition\"", "", "4900.00") },
 105             { "1999,Chevy,\"Venture \"\"Extended Edition, Very Large\"\"\",,5000.00",
 106                 List.of("1999", "Chevy", "Venture \"Extended Edition, Very Large\"", "", "5000.00") },
 107             { "1996,Jeep,Grand Cherokee,\"MUST SELL!\nair, moon roof, loaded\",4799.00",
 108                 List.of("1996", "Jeep", "Grand Cherokee", "MUST SELL!\nair, moon roof, loaded", "4799.00") }
 109         };
 110     }
 111 
 112     @Test(dataProvider = "csvdata")
 113     public void roundTrip(String input, List<String> parsed) {
 114         List<String> actual = CSV.split(input);
 115         assertEquals(actual, parsed);
 116         CSV.write(out, actual.toArray());
 117         checkString(input);
 118     }
 119 
 120     // won't round-trip
 121     public void testExtraQuote() {
 122         assertEquals(CSV.split("a,\"b\",c"), List.of("a", "b", "c"));
 123     }
 124 
 125     // won't round-trip
 126     public void testEmptyQuote() {
 127         assertEquals(CSV.split("a,\"\",b"), List.of("a", "", "b"));
 128     }
 129 
 130     @Test(expectedExceptions=CSVParseException.class)
 131     public void errorUnexpectedQuote() {
 132         CSV.split("ab\"cd");
 133     }
 134 
 135     @Test(expectedExceptions=CSVParseException.class)
 136     public void errorCharacterAfterQuote() {
 137         CSV.split("a,\"b\"c,d");
 138     }
 139 
 140     @Test(expectedExceptions=CSVParseException.class)
 141     public void errorUnclosedQuote() {
 142         CSV.split("a,\"b");
 143     }
 144 }