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.EncodingControl; 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", new EncodingControl("UTF-8"))); } @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)は、整数として不正です。"); } } }