/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.runtime.io.text.csv;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.function.UnaryOperator;
import org.junit.Test;
import com.asakusafw.runtime.io.text.LineSeparator;
import com.asakusafw.runtime.io.text.driver.BasicFieldOutput;
/**
* Test for {@link CsvTextFormat}.
*/
public class CsvTextFormatTest {
/**
* input.
*/
@Test
public void input() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[][] results = read(format, new String[] {
"Hello!",
});
assertThat(results, is(new String[][] {
{ "Hello!" },
}));
}
/**
* input - quoted.
*/
@Test
public void input_quoted() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[][] results = read(format, new String[] {
"\"Hello, world!\"",
});
assertThat(results, is(new String[][] {
{ "Hello, world!" },
}));
}
/**
* input - delimited.
*/
@Test
public void input_delimited() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[][] results = read(format, new String[] {
"A,B",
"C,D",
});
assertThat(results, is(new String[][] {
{ "A", "B", },
{ "C", "D", },
}));
}
/**
* input - charset.
*/
@Test
public void input_charset() {
CsvTextFormat format = CsvTextFormat.builder()
.withCharset("US-ASCII")
.build();
String[][] results = read(format, new String[] {
"A,B",
"C,D",
});
assertThat(results, is(new String[][] {
{ "A", "B", },
{ "C", "D", },
}));
}
/**
* input - w/ field separator.
*/
@Test
public void input_field_separator() {
CsvTextFormat format = CsvTextFormat.builder()
.withFieldSeparator('\t')
.build();
String[][] results = read(format, new String[] {
"A\tB",
"C\tD",
});
assertThat(results, is(new String[][] {
{ "A", "B", },
{ "C", "D", },
}));
}
/**
* input - w/ quote character.
*/
@Test
public void input_quote_character() {
CsvTextFormat format = CsvTextFormat.builder()
.withQuoteCharacter('%')
.build();
String[][] results = read(format, new String[] {
"%Hello, world!%",
});
assertThat(results, is(new String[][] {
{ "Hello, world!", },
}));
}
/**
* input - w/ allow line feed in field.
*/
@Test
public void input_allow_line_feed() {
CsvTextFormat format = CsvTextFormat.builder()
.withAllowLineFeedInField(true)
.build();
String[][] results = read(format, new String[] {
"\"A\nB\nC\n\"",
});
assertThat(results, is(new String[][] {
{ "A\nB\nC\n", },
}));
}
/**
* input - w/ transformer.
*/
@Test
public void input_transformer() {
CsvTextFormat format = CsvTextFormat.builder()
.withInputTransformer(LowerCaseTransformer.class)
.build();
String[][] results = read(format, new String[] {
"A,B",
"C,D",
});
assertThat(results, is(new String[][] {
{ "a", "b", },
{ "c", "d", },
}));
}
/**
* output.
*/
@Test
public void output() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[] results = write(format, new String[][] {
{ "Hello!", },
});
assertThat(results, is(new String[] {
"Hello!",
}));
}
/**
* output - quote.
*/
@Test
public void output_quoted() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[] results = write(format, new String[][] {
{ "Hello, world!!", },
});
assertThat(results, is(new String[] {
"\"Hello, world!!\"",
}));
}
/**
* output - delimited.
*/
@Test
public void output_delimited() {
CsvTextFormat format = CsvTextFormat.builder()
.build();
String[] results = write(format, new String[][] {
{ "A", "B", },
{ "C", "D", },
});
assertThat(results, is(new String[] {
"A,B",
"C,D",
}));
}
/**
* output - charset.
*/
@Test
public void output_charset() {
CsvTextFormat format = CsvTextFormat.builder()
.withCharset("US-ASCII")
.build();
String[] results = write(format, new String[][] {
{ "A", "B", },
{ "C", "D", },
});
assertThat(results, is(new String[] {
"A,B",
"C,D",
}));
}
/**
* output - w/ line separator.
*/
@Test
public void output_line_separator() {
CsvTextFormat format = CsvTextFormat.builder()
.withLineSeparator(LineSeparator.UNIX)
.build();
String[] results = write(format, new String[][] {
{ "A", "B", },
{ "C", "D", },
});
assertThat(results, is(new String[] {
"A,B",
"C,D",
}));
}
/**
* output - w/ field separator.
*/
@Test
public void output_field_separator() {
CsvTextFormat format = CsvTextFormat.builder()
.withFieldSeparator('\t')
.build();
String[] results = write(format, new String[][] {
{ "A", "B", },
{ "C", "D", },
});
assertThat(results, is(new String[] {
"A\tB",
"C\tD",
}));
}
/**
* output - w/ quote character.
*/
@Test
public void output_quote_character() {
CsvTextFormat format = CsvTextFormat.builder()
.withQuoteCharacter('%')
.build();
String[] results = write(format, new String[][] {
{ "Hello, world!", },
});
assertThat(results, is(new String[] {
"%Hello, world!%",
}));
}
/**
* output - w/ allow line feed in field.
*/
@Test
public void output_allow_line_feed_in_field() {
CsvTextFormat format = CsvTextFormat.builder()
.withAllowLineFeedInField(true)
.build();
String[] results = write(format, new String[][] {
{ "A\nB\nC\n", },
});
assertThat(results, is(new String[] {
"\"A\nB\nC\n\"",
}));
}
/**
* output - w/ default quote style.
*/
@Test
public void output_default_quote_style() {
CsvTextFormat format = CsvTextFormat.builder()
.withDefaultQuoteStyle(QuoteStyle.ALWAYS)
.build();
String[] results = write(format, new String[][] {
{ "Hello!", },
});
assertThat(results, is(new String[] {
"\"Hello!\"",
}));
}
/**
* output - w/ header quote style.
*/
@Test
public void output_header_quote_style() {
CsvTextFormat format = CsvTextFormat.builder()
.withHeaderQuoteStyle(QuoteStyle.ALWAYS)
.build();
String[] results = write(format, new String[][] {
{ "Hello!", },
});
assertThat(results, is(new String[] {
"Hello!",
}));
}
/**
* output - w/ transformer.
*/
@Test
public void output_transformer() {
CsvTextFormat format = CsvTextFormat.builder()
.withOutputTransformer(LowerCaseTransformer.class)
.build();
String[] results = write(format, new String[][] {
{ "A", "B", },
{ "C", "D", },
});
assertThat(results, is(new String[] {
"a,b",
"c,d",
}));
}
private static String[][] read(CsvTextFormat format, String... lines) {
StringBuilder buffer = new StringBuilder();
for (String line : lines) {
buffer.append(line);
buffer.append(format.getLineSeparator().getSequence());
}
byte[] bytes = buffer.toString().getBytes(format.getCharset());
try (CsvFieldReader reader = format.open(new ByteArrayInputStream(bytes))) {
List<List<String>> results = new ArrayList<>();
while (reader.nextRecord()) {
List<String> row = new ArrayList<>();
while (reader.nextField()) {
CharSequence content = reader.getContent();
row.add(content == null ? null : content.toString());
}
results.add(row);
}
return results.stream()
.map(s -> s.stream().toArray(String[]::new))
.toArray(String[][]::new);
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static String[] write(CsvTextFormat format, String[][] fields) {
BasicFieldOutput fout = new BasicFieldOutput();
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (CsvFieldWriter writer = format.open(output)) {
for (String[] row : fields) {
for (String field : row) {
writer.putField(fout.set(field));
}
writer.putEndOfRecord();
}
} catch (IOException e) {
throw new AssertionError(e);
}
String lines = new String(output.toByteArray(), format.getCharset());
return Arrays.stream(lines.split(format.getLineSeparator().getSequence()))
.filter(s -> s.isEmpty() == false)
.toArray(String[]::new);
}
@SuppressWarnings("javadoc")
public static class LowerCaseTransformer implements UnaryOperator<CharSequence> {
@Override
public CharSequence apply(CharSequence t) {
return t.toString().toLowerCase(Locale.ENGLISH);
}
}
}