package com.github.mygreen.supercsv.builder;
import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;
import static com.github.mygreen.supercsv.tool.TestUtils.*;
import static com.github.mygreen.supercsv.tool.HasCellProcessorAssert.*;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.supercsv.cellprocessor.FmtNumber;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.Trim;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCsvCellProcessorException;
import org.supercsv.exception.SuperCsvConstraintViolationException;
import com.github.mygreen.supercsv.annotation.CsvBean;
import com.github.mygreen.supercsv.annotation.CsvColumn;
import com.github.mygreen.supercsv.localization.MessageResolver;
import com.github.mygreen.supercsv.localization.ResourceBundleMessageResolver;
import com.github.mygreen.supercsv.validation.CsvExceptionConverter;
/**
* {@link ProcessorBuilder}のテスタ
*
* @since 2.0
* @author T.TSUCHIE
*
*/
public class ProcesssorBuilderTest {
@Rule
public TestName name = new TestName();
private BeanMappingFactory beanMappingFactory;
private CsvExceptionConverter exceptionConverter;
private final Class<?>[] groupEmpty = new Class[]{};
private MessageResolver testMessageResolver;
@Before
public void setUp() throws Exception {
this.beanMappingFactory = new BeanMappingFactory();
this.exceptionConverter = new CsvExceptionConverter();
this.testMessageResolver = new ResourceBundleMessageResolver(ResourceBundle.getBundle("TestMessages"));
}
@CsvBean
private static class TestCsv {
@CsvColumn(number=1, builder=CustomProcessorBuilder.class)
private Integer col_default;
}
private static class CustomProcessorBuilder implements ProcessorBuilder<Integer> {
@Override
public Optional<CellProcessor> buildForReading(final Class<Integer> type, final FieldAccessor field,
final Configuration config, final Class<?>[] groups) {
CellProcessor processor = new NotNull(new Trim(new ParseInt()));
return Optional.of(processor);
}
@Override
public Optional<CellProcessor> buildForWriting(final Class<Integer> type, final FieldAccessor field,
final Configuration config, final Class<?>[] groups) {
CellProcessor processor = new NotNull(new FmtNumber(new DecimalFormat("#,##0")));
return Optional.of(processor);
}
}
@Test
public void testRead() {
BeanMapping<TestCsv> beanMapping = beanMappingFactory.create(TestCsv.class, groupEmpty);
ColumnMapping columnMapping = beanMapping.getColumnMapping("col_default").get();
CellProcessor processor = columnMapping.getCellProcessorForReading();
printCellProcessorChain(processor, name.getMethodName());
{
// null input
String input = null;
assertThatThrownBy(() -> processor.execute(input, testCsvContext(columnMapping, input)))
.isInstanceOf(SuperCsvConstraintViolationException.class);
}
{
// valid input
String input = " 100 ";
Integer expected = 100;
assertThat((Object)processor.execute(input, testCsvContext(columnMapping, input))).isEqualTo(expected);
}
{
// wrong input - wrong format
String input = "abc";
try {
processor.execute(input, testCsvContext(columnMapping, input));
fail();
} catch(Exception e) {
assertThat(e).isInstanceOf(SuperCsvCellProcessorException.class);
SuperCsvCellProcessorException processorException = (SuperCsvCellProcessorException)e;
assertThat(processorException.getProcessor()).isInstanceOf(ParseInt.class);
}
}
}
@Test
public void testWite() {
BeanMapping<TestCsv> beanMapping = beanMappingFactory.create(TestCsv.class, groupEmpty);
ColumnMapping columnMapping = beanMapping.getColumnMapping("col_default").get();
CellProcessor processor = columnMapping.getCellProcessorForWriting();
printCellProcessorChain(processor, name.getMethodName());
{
// null input
Integer input = null;
assertThatThrownBy(() -> processor.execute(input, testCsvContext(columnMapping, input)))
.isInstanceOf(SuperCsvConstraintViolationException.class);
}
{
// valid input
Integer input = 10_000;
String expected = "10,000";
assertThat((Object)processor.execute(input, testCsvContext(columnMapping, input))).isEqualTo(expected);
}
}
@Test
public void testErrorMessage_default() {
BeanMapping<TestCsv> beanMapping = beanMappingFactory.create(TestCsv.class, groupEmpty);
ColumnMapping columnMapping = beanMapping.getColumnMapping("col_default").get();
CellProcessor processor = columnMapping.getCellProcessorForReading();
printCellProcessorChain(processor, name.getMethodName());
// wrong input - wrong format
String input = "abc";
try {
processor.execute(input, testCsvContext(columnMapping, input));
fail();
} catch(Exception e) {
assertThat(e).isInstanceOf(SuperCsvCellProcessorException.class);
SuperCsvCellProcessorException processorException = (SuperCsvCellProcessorException)e;
assertThat(processorException.getProcessor()).isInstanceOf(ParseInt.class);
List<String> messages = exceptionConverter.convertAndFormat((SuperCsvCellProcessorException)e, beanMapping);
assertThat(messages).hasSize(1)
.contains("'abc' could not be parsed as an Integer");
}
}
/**
* CellProcessor名で別途定義する
*/
@Test
public void testErrorMessage_custom() {
// メッセージの入れ替え
exceptionConverter.setMessageResolver(testMessageResolver);
BeanMapping<TestCsv> beanMapping = beanMappingFactory.create(TestCsv.class, groupEmpty);
ColumnMapping columnMapping = beanMapping.getColumnMapping("col_default").get();
CellProcessor processor = columnMapping.getCellProcessorForReading();
printCellProcessorChain(processor, name.getMethodName());
// wrong input - wrong format
String input = "abc";
try {
processor.execute(input, testCsvContext(columnMapping, input));
fail();
} catch(Exception e) {
assertThat(e).isInstanceOf(SuperCsvCellProcessorException.class);
SuperCsvCellProcessorException processorException = (SuperCsvCellProcessorException)e;
assertThat(processorException.getProcessor()).isInstanceOf(ParseInt.class);
List<String> messages = exceptionConverter.convertAndFormat((SuperCsvCellProcessorException)e, beanMapping);
assertThat(messages).hasSize(1)
.contains("[2行, 1列] : 項目「col_default」の値(abc)は、整数として不正です。");
}
}
}