package com.github.mygreen.supercsv.io;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import static com.github.mygreen.supercsv.tool.TestUtils.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.supercsv.exception.SuperCsvException;
import org.supercsv.prefs.CsvPreference;
import com.github.mygreen.supercsv.annotation.DefaultGroup;
import com.github.mygreen.supercsv.builder.BeanMapping;
import com.github.mygreen.supercsv.builder.BeanMappingFactory;
import com.github.mygreen.supercsv.exception.SuperCsvBindingException;
import com.github.mygreen.supercsv.exception.SuperCsvNoMatchColumnSizeException;
import com.github.mygreen.supercsv.exception.SuperCsvNoMatchHeaderException;
import com.github.mygreen.supercsv.validation.CsvExceptionConverter;
/**
* {@link CsvAnnotationBeanReader}のテスタ。
*
* @version 2.0.2
* @since 1.2
* @author T.TSUCHIE
*
*/
public class CsvAnnotationBeanReaderTest {
private CsvExceptionConverter exceptionConverter;
@Before
public void setUp() throws Exception {
this.exceptionConverter = new CsvExceptionConverter();
}
/**
* 正常系のテスト - コンストラクタのテスト
* <p> BeanMappingの指定</p>
* @throws IOException
*/
@Test
public void testConstructor_beanMapping() throws IOException {
File file = new File("src/test/data/test_read_normal.csv");
BeanMappingFactory mappingFactory = new BeanMappingFactory();
BeanMapping<SampleNormalBean> beanMapping = mappingFactory.create(SampleNormalBean.class,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
beanMapping,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE);
List<SampleNormalBean> list = new ArrayList<>();
// read header
final String[] csvHeaders = csvReader.getHeader(true);
assertThat(csvHeaders).isNotNull();
SampleNormalBean bean;
while((bean = csvReader.read()) != null) {
list.add(bean);
assertBean(bean);
}
assertThat(csvReader.getErrorMessages()).hasSize(0);
csvReader.close();
}
/**
* 正常系のテスト
* @throws IOException
*/
@Test
public void testRead_normal() throws IOException {
File file = new File("src/test/data/test_read_normal.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = new ArrayList<>();
final String[] expectedHeaders = new String[]{
"id",
"数字1", "number2",
"string1", "string2",
"date1", "date2",
"enum1", "列挙型2",
"boolean1", "boolean2"
};
final String[] definitionHeaders = csvReader.getDefinedHeader();
assertThat(definitionHeaders).containsExactly(expectedHeaders);
// read header
final String[] csvHeaders = csvReader.getHeader(true);
assertThat(csvHeaders).containsExactly(expectedHeaders);
SampleNormalBean bean;
while((bean = csvReader.read()) != null) {
list.add(bean);
assertBean(bean);
}
assertThat(csvReader.getErrorMessages()).hasSize(0);
csvReader.close();
}
/**
* ヘッダーの列数が一致しない
*/
@Test
public void testRead_error_header_size() throws IOException {
File file = new File("src/test/data/test_read_error_header_size.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = new ArrayList<>();
try {
final String[] headers = csvReader.getHeader(true);
fail();
} catch(SuperCsvException e) {
assertThat(e).isInstanceOf(SuperCsvNoMatchColumnSizeException.class);
// e.printStackTrace();
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[1行] : 列数が不正です。 11列で設定すべきですが、実際には10列になっています。");
messages.forEach(System.out::println);
csvReader.close();
}
//TODO: XMLの機能を実装した後に、書き換える。
// /**
// * ヘッダーの列数が一致しない(チェックを無視する場合)
// */
// @Test
// public void testRead_error_header_size_ignore() throws IOException {
//
// File file = new File("src/test/data/test_read_error_header_size.csv");
//
// CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
// SampleNormalBean.class,
// new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
// CsvPreference.STANDARD_PREFERENCE);
// csvReader.setExceptionConverter(exceptionConverter);
//
// List<SampleNormalBean> list = new ArrayList<>();
//
// String[] headers = csvReader.getHeader(false);
// assertThat(headers, is(notNullValue()));
//
//
// csvReader.close();
//
// }
/**
* ヘッダの値が一致しない
*/
@Test
public void testRead_error_header_value() throws IOException {
File file = new File("src/test/data/test_read_error_header_value.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = new ArrayList<>();
try {
// read header
final String headers[] = csvReader.getHeader(true);
fail();
} catch(SuperCsvException e) {
assertThat(e).isInstanceOf(SuperCsvNoMatchHeaderException.class);
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[1行] : ヘッダーの値「id, 間違い, number2, string1, string2, date1, date2, enum1, 列挙型2, boolean1, boolean2」は、「id, 数字1, number2, string1, string2, date1, date2, enum1, 列挙型2, boolean1, boolean2」と一致しません。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 列のサイズが一致しない
*/
@Test
public void testRead_error_column_size() throws IOException {
File file = new File("src/test/data/test_read_error_column_size.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = new ArrayList<>();
// read header
final String headers[] = csvReader.getHeader(true);
try {
SampleNormalBean bean;
while((bean = csvReader.read()) != null) {
list.add(bean);
assertBean(bean);
}
fail();
} catch(SuperCsvException e) {
assertThat(e).isInstanceOf(SuperCsvNoMatchColumnSizeException.class);
// e.printStackTrace();
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[3行] : 列数が不正です。 11列で設定すべきですが、実際には13列になっています。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 列のパターンが不正な場合
*/
@Test
public void testRead_error_wrong_pattern() throws IOException {
File file = new File("src/test/data/test_read_error_wrong_pattern.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = new ArrayList<>();
// read header
final String headers[] = csvReader.getHeader(true);
try {
SampleNormalBean bean;
while((bean = csvReader.read()) != null) {
list.add(bean);
assertBean(bean);
}
fail();
} catch(SuperCsvException e) {
assertThat(e).isInstanceOf(SuperCsvBindingException.class);
// e.printStackTrace();
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[2行, 6列] : 項目「date1」の値(2000/01/01 00:01:02)の書式は不正です。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 全件読み込み(正常系のテスト)
*/
@Test
public void testReadAll_normal() throws IOException {
File file = new File("src/test/data/test_read_normal.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = csvReader.readAll();
assertThat(list).hasSize(2);
for(SampleNormalBean bean : list) {
assertBean(bean);
}
assertThat(csvReader.getErrorMessages()).hasSize(0);
csvReader.close();
}
/**
* 全件読み込み - カラムにエラーがある
*/
@Test
public void testReadAll_error_column() throws IOException {
File file = new File("src/test/data/test_read_error_wrong_pattern.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
try {
List<SampleNormalBean> list = csvReader.readAll();
} catch(Exception e) {
assertThat(e).isInstanceOf(SuperCsvBindingException.class);
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[2行, 6列] : 項目「date1」の値(2000/01/01 00:01:02)の書式は不正です。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 全件読み込み - カラムにエラーがある場合も処理を続ける
*/
@Test
public void testReadAll_error_continueOnError() throws IOException {
File file = new File("src/test/data/test_read_error_wrong_pattern.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = csvReader.readAll(true);
assertThat(list).hasSize(1);
for(SampleNormalBean bean : list) {
assertBean(bean);
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[2行, 6列] : 項目「date1」の値(2000/01/01 00:01:02)の書式は不正です。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 全件読み込み - ヘッダーにエラーがある場合
*/
@Test
public void testReadAll_error_header_size() throws IOException {
File file = new File("src/test/data/test_read_error_header_size.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
try {
List<SampleNormalBean> list = csvReader.readAll();
} catch(Exception e) {
assertThat(e).isInstanceOf(SuperCsvNoMatchColumnSizeException.class);
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[1行] : 列数が不正です。 11列で設定すべきですが、実際には10列になっています。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 全件読み込み - ヘッダーにエラーがある場合 - エラーがあっても処理を続ける
*/
@Test
public void testReadAll_error_header_size_continueOnError() throws IOException {
File file = new File("src/test/data/test_read_error_header_size.csv");
CsvAnnotationBeanReader<SampleNormalBean> csvReader = new CsvAnnotationBeanReader<>(
SampleNormalBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SampleNormalBean> list = csvReader.readAll(true);
assertThat(list).hasSize(2);
for(SampleNormalBean bean : list) {
assertBean(bean);
}
// convert error messages.
List<String> messages = csvReader.getErrorMessages();
assertThat(messages).hasSize(1)
.contains("[1行] : 列数が不正です。 11列で設定すべきですが、実際には10列になっています。");
messages.forEach(System.out::println);
csvReader.close();
}
/**
* 部分的にカラムを読み込む
*/
@Test
public void testRead_partial() throws IOException {
File file = new File("src/test/data/test_read_normal.csv");
CsvAnnotationBeanReader<SamplePartialBean> csvReader = new CsvAnnotationBeanReader<>(
SamplePartialBean.class,
new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
CsvPreference.STANDARD_PREFERENCE,
DefaultGroup.class, SampleNormalBean.ReadGroup.class);
csvReader.setExceptionConverter(exceptionConverter);
List<SamplePartialBean> list = new ArrayList<>();
final String[] expectedHeaders = new String[]{
"id",
"数字1", "number2",
"string1", "string2",
"date1", "date2",
"enum1", "列挙型2",
"boolean1", "boolean2"
};
final String[] definitionHeaders = csvReader.getDefinedHeader();
assertThat(definitionHeaders).containsExactly(expectedHeaders);
// read header
final String[] csvHeaders = csvReader.getHeader(true);
assertThat(csvHeaders).containsExactly(expectedHeaders);
SamplePartialBean bean;
while((bean = csvReader.read()) != null) {
list.add(bean);
assertBean(bean);
}
assertThat(csvReader.getErrorMessages()).hasSize(0);
csvReader.close();
}
private void assertBean(final SampleNormalBean bean) {
if(bean.getId() == 1) {
assertThat(bean.getNumber1()).isEqualTo(999110);
assertThat(bean.getNumber2()).isEqualTo(10.2d);
assertThat(bean.getString1()).isEqualTo("abcd");
assertThat(bean.getString2()).isEqualTo("12345");
assertThat(bean.getDate1()).isEqualTo(toDate(2000, 1, 1, 0, 1, 2));
assertThat(bean.getDate2()).isEqualTo(toTimestamp(toDate(2000, 2, 3)));
assertThat(bean.getEnum1()).isEqualTo(SampleEnum.RED);
assertThat(bean.getEnum2()).isEqualTo(SampleEnum.RED);
assertThat(bean.isBoolean1()).isEqualTo(true);
assertThat(bean.getBoolean2()).isEqualTo(Boolean.TRUE);
} else if(bean.getId() == 2) {
assertThat(bean.getNumber1()).isEqualTo(-12);
assertThat(bean.getNumber2()).isNull();
assertThat(bean.getString1()).isEqualTo("あいうえお");
assertThat(bean.getString2()).isEqualTo("");
assertThat(bean.getDate1()).isEqualTo(toDate(2000, 2, 1, 3, 4, 5));
assertThat(bean.getDate2()).isNull();;
assertThat(bean.getEnum1()).isEqualTo(SampleEnum.BLUE);
assertThat(bean.getEnum2()).isEqualTo(SampleEnum.BLUE);
assertThat(bean.isBoolean1()).isEqualTo(false);
assertThat(bean.getBoolean2()).isEqualTo(Boolean.FALSE);
}
}
private void assertBean(final SamplePartialBean bean) {
if(bean.getId() == 1) {
assertThat(bean.getNumber1()).isEqualTo(999110);
assertThat(bean.getString1()).isEqualTo("abcd");
assertThat(bean.getDate1()).isEqualTo(toDate(2000, 1, 1, 0, 1, 2));
assertThat(bean.getEnum1()).isEqualTo(SampleEnum.RED);
assertThat(bean.isBoolean1()).isEqualTo(true);
} else if(bean.getId() == 2) {
assertThat(bean.getNumber1()).isEqualTo(-12);
assertThat(bean.getString1()).isEqualTo("あいうえお");
assertThat(bean.getDate1()).isEqualTo(toDate(2000, 2, 1, 3, 4, 5));
assertThat(bean.getEnum1()).isEqualTo(SampleEnum.BLUE);
assertThat(bean.isBoolean1()).isEqualTo(false);
}
}
}