View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
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  package org.supercsv.io;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.supercsv.SuperCsvTestUtils.HEADER;
20  import static org.supercsv.SuperCsvTestUtils.HEADER_CSV;
21  
22  import java.io.IOException;
23  import java.io.StringWriter;
24  import java.io.Writer;
25  
26  import org.junit.After;
27  import org.junit.Before;
28  import org.junit.Test;
29  import org.supercsv.prefs.CsvPreference;
30  
31  /**
32   * Tests AbstractCsvWriter.
33   * 
34   * @author Kasper B. Graversen
35   * @author James Bassett
36   */
37  public class AbstractCsvWriterTest {
38  	
39  	private static final CsvPreference PREFS = CsvPreference.STANDARD_PREFERENCE;
40  	private static final CsvPreference SURROUNDING_SPACES_REQUIRE_QUOTES_PREFS = new CsvPreference.Builder(
41  		CsvPreference.STANDARD_PREFERENCE).surroundingSpacesNeedQuotes(true).build();
42  	
43  	private Writer writer;
44  	
45  	private AbstractCsvWriter abstractWriter;
46  	private AbstractCsvWriter surroundingSpacesNeedQuotesAbstractWriter;
47  	
48  	/**
49  	 * Implementation of AbstractCsvWriter for testing.
50  	 */
51  	static class MockCsvWriter extends AbstractCsvWriter {
52  		
53  		private CsvPreference preference;
54  		
55  		public MockCsvWriter(Writer writer, CsvPreference preference) {
56  			super(writer, preference);
57  			this.preference = preference;
58  		}
59  	}
60  	
61  	/**
62  	 * Sets up the writer for the tests.
63  	 */
64  	@Before
65  	public void setUp() {
66  		writer = new StringWriter();
67  		abstractWriter = new MockCsvWriter(writer, PREFS);
68  		surroundingSpacesNeedQuotesAbstractWriter = new MockCsvWriter(writer, SURROUNDING_SPACES_REQUIRE_QUOTES_PREFS);
69  	}
70  	
71  	/**
72  	 * Closes the writer after the test.
73  	 */
74  	@After
75  	public void tearDown() throws IOException {
76  		abstractWriter.close();
77  		surroundingSpacesNeedQuotesAbstractWriter.close();
78  	}
79  	
80  	/**
81  	 * Tests the writeHeader() method.
82  	 */
83  	@Test
84  	public void testWriteHeader() throws IOException {
85  		assertEquals(0, abstractWriter.getLineNumber());
86  		assertEquals(0, abstractWriter.getRowNumber());
87  		
88  		abstractWriter.writeHeader(HEADER);
89  		
90  		assertEquals(1, abstractWriter.getLineNumber());
91  		assertEquals(1, abstractWriter.getRowNumber());
92  		
93  		abstractWriter.flush();
94  		assertEquals(HEADER_CSV + "\r\n", writer.toString());
95  	}
96  	
97  	/**
98  	 * Tests the writeComment() method.
99  	 */
100 	@Test
101 	public void testWriteComment() throws IOException {
102 		assertEquals(0, abstractWriter.getLineNumber());
103 		assertEquals(0, abstractWriter.getRowNumber());
104 		
105 		final String comment = "#this is a comment";
106 		abstractWriter.writeComment(comment);
107 		assertEquals(1, abstractWriter.getLineNumber());
108 		assertEquals(0, abstractWriter.getRowNumber());
109 		
110 		final String header = "this,is,the,header";
111 		abstractWriter.writeHeader(header.split(","));
112 		assertEquals(2, abstractWriter.getLineNumber());
113 		assertEquals(1, abstractWriter.getRowNumber());
114 		
115 		abstractWriter.writeComment(comment);
116 		assertEquals(3, abstractWriter.getLineNumber());
117 		assertEquals(1, abstractWriter.getRowNumber());
118 		
119 		abstractWriter.writeHeader(header.split(","));
120 		assertEquals(4, abstractWriter.getLineNumber());
121 		assertEquals(2, abstractWriter.getRowNumber());
122 		
123 		abstractWriter.flush();
124 		final String eol = PREFS.getEndOfLineSymbols();
125 		final String expected = comment + eol + header + eol + comment + eol + header + eol;
126 		assertEquals(expected, writer.toString());
127 	}
128 	
129 	/**
130 	 * Tests that all 3 variations of line terminators embedded in CSV are handled correctly (are replaced with the end
131 	 * of line symbols and line number is incremented correctly). writeHeader() is used because it increments the line
132 	 * number just like the write() methods exposed on concretes writers.
133 	 * 
134 	 * @param csvWriter
135 	 *            the CSV writer
136 	 * @param prefs
137 	 *            the preferences
138 	 * @throws IOException
139 	 */
140 	private void writeHeaderWithEmbeddedEndOfLineSymbols(final MockCsvWriter csvWriter) throws IOException {
141 		
142 		final String eolSymbols = csvWriter.preference.getEndOfLineSymbols();
143 		
144 		final String textWithNewline = "text that\nspans\nthree lines";
145 		final String textWithCarriageReturn = "text that\rspans\rthree lines";
146 		final String textWithCarriageAndNewline = "text that\r\nspans\r\nthree lines";
147 		
148 		final String expected = "\"text that" + eolSymbols + "spans" + eolSymbols + "three lines\"" + eolSymbols;
149 		
150 		// \n
151 		csvWriter.writeHeader(textWithNewline);
152 		csvWriter.flush();
153 		assertEquals(expected, writer.toString());
154 		assertEquals(3, csvWriter.getLineNumber());
155 		assertEquals(1, csvWriter.getRowNumber());
156 		
157 		// \r
158 		csvWriter.writeHeader(textWithCarriageReturn);
159 		csvWriter.flush();
160 		assertEquals(expected + expected, writer.toString());
161 		assertEquals(6, csvWriter.getLineNumber());
162 		assertEquals(2, csvWriter.getRowNumber());
163 		
164 		// \r\n
165 		csvWriter.writeHeader(textWithCarriageAndNewline);
166 		csvWriter.flush();
167 		assertEquals(expected + expected + expected, writer.toString());
168 		assertEquals(9, csvWriter.getLineNumber());
169 		assertEquals(3, csvWriter.getRowNumber());
170 		
171 		// \r\n\n (checks that skipNewline only skips 1 newline)
172 		csvWriter.writeHeader("\r\n\n");
173 		csvWriter.flush();
174 		assertEquals(expected + expected + expected + "\"" + eolSymbols + eolSymbols + "\"" + eolSymbols,
175 			writer.toString());
176 		assertEquals(12, csvWriter.getLineNumber());
177 		assertEquals(4, csvWriter.getRowNumber());
178 		
179 		csvWriter.close();
180 	}
181 	
182 	/**
183 	 * Tests the writeHeader() method with an embedded carriage return and newline (i.e. Windows).
184 	 */
185 	@Test
186 	public void testWriteHeaderWithCarriageReturnNewline() throws IOException {
187 		writeHeaderWithEmbeddedEndOfLineSymbols(new MockCsvWriter(writer, CsvPreference.STANDARD_PREFERENCE));
188 	}
189 	
190 	/**
191 	 * Tests the writeHeader() method with an embedded newline (i.e. Linux).
192 	 */
193 	@Test
194 	public void testWriteHeaderWithNewline() throws IOException {
195 		writeHeaderWithEmbeddedEndOfLineSymbols(new MockCsvWriter(writer, CsvPreference.EXCEL_PREFERENCE));
196 	}
197 	
198 	/**
199 	 * Tests the writeHeader() method with an embedded carriage return (i.e. Mac).
200 	 */
201 	@Test
202 	public void testWriteHeaderWithCarriageReturn() throws IOException {
203 		writeHeaderWithEmbeddedEndOfLineSymbols(new MockCsvWriter(writer,
204 			new CsvPreference.Builder('"', ',', "\r").build()));
205 	}
206 	
207 	/**
208 	 * Tests the writeComment() method with a null String.
209 	 */
210 	@Test(expected = NullPointerException.class)
211 	public void writeCommentWithNull() throws IOException {
212 		abstractWriter.writeComment(null);
213 	}
214 	
215 	/**
216 	 * Tests the writeHeader() method with a null array.
217 	 */
218 	@Test(expected = NullPointerException.class)
219 	public void writeHeaderWithNull() throws IOException {
220 		abstractWriter.writeHeader((String[]) null);
221 	}
222 	
223 	/**
224 	 * Tests the writeHeader() method with an empty array.
225 	 */
226 	@Test(expected = IllegalArgumentException.class)
227 	public void writeHeaderWithEmptyArray() throws IOException {
228 		abstractWriter.writeHeader(new String[] {});
229 	}
230 	
231 	/**
232 	 * Tests the constructor with a null writer.
233 	 */
234 	@SuppressWarnings("resource")
235 	@Test(expected = NullPointerException.class)
236 	public void testConstructorWithNullWriter() {
237 		new MockCsvWriter(null, PREFS);
238 	}
239 	
240 	/**
241 	 * Tests the constructor with a null preference.
242 	 */
243 	@SuppressWarnings("resource")
244 	@Test(expected = NullPointerException.class)
245 	public void testConstructorWithNullPreferences() {
246 		new MockCsvWriter(writer, null);
247 	}
248 }