package com.gh.mygreen.xlsmapper.cellconvert; import static com.gh.mygreen.xlsmapper.TestUtils.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.awt.Point; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; import com.gh.mygreen.xlsmapper.IsEmptyBuilder; import com.gh.mygreen.xlsmapper.XlsMapper; import com.gh.mygreen.xlsmapper.annotation.OverRecordOperate; import com.gh.mygreen.xlsmapper.annotation.RecordTerminal; import com.gh.mygreen.xlsmapper.annotation.XlsColumn; import com.gh.mygreen.xlsmapper.annotation.XlsConverter; import com.gh.mygreen.xlsmapper.annotation.XlsEnumConverter; import com.gh.mygreen.xlsmapper.annotation.XlsFormula; import com.gh.mygreen.xlsmapper.annotation.XlsHint; import com.gh.mygreen.xlsmapper.annotation.XlsHorizontalRecords; import com.gh.mygreen.xlsmapper.annotation.XlsIsEmpty; import com.gh.mygreen.xlsmapper.annotation.XlsSheet; import com.gh.mygreen.xlsmapper.cellconvert.converter.EnumCellConverter; import com.gh.mygreen.xlsmapper.validation.SheetBindingErrors; /** * {@link EnumCellConverter}のテスタ * * @version 1.5 * @since 0.5 * @author T.TSUCHIE * */ public class EnumCellConverterTest { /** * テスト結果ファイルの出力ディレクトリ */ private static File OUT_DIR; @BeforeClass public static void setUpBeforeClass() throws Exception { OUT_DIR = createOutDir(); } /** * 列挙型の読み込みテスト */ @Test public void test_load_enum() throws Exception { XlsMapper mapper = new XlsMapper(); mapper.getConig().setContinueTypeBindFailure(true); try(InputStream in = new FileInputStream("src/test/data/convert.xlsx")) { SheetBindingErrors errors = new SheetBindingErrors(EnumSheet.class); EnumSheet sheet = mapper.load(in, EnumSheet.class, errors); if(sheet.simpleRecords != null) { for(SimpleRecord record : sheet.simpleRecords) { assertRecord(record, errors); } } if(sheet.formattedRecords != null) { for(FormattedRecord record : sheet.formattedRecords) { assertRecord(record, errors); } } if(sheet.formulaRecords != null) { for(FormulaRecord record : sheet.formulaRecords) { assertRecord(record, errors); } } } } private void assertRecord(final SimpleRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.color, is(nullValue())); assertThat(record.operate, is(nullValue())); } else if(record.no == 2) { // 正しい値 assertThat(record.color, is(Color.Red)); assertThat(record.operate, is(Operate.Refer)); } else if(record.no == 3) { // 不正な値 assertThat(cellFieldError(errors, cellAddress(record.positions.get("color"))).isTypeBindFailure(), is(true)); assertThat(cellFieldError(errors, cellAddress(record.positions.get("operate"))).isTypeBindFailure(), is(true)); } else if(record.no == 4) { // 小文字 assertThat(cellFieldError(errors, cellAddress(record.positions.get("color"))).isTypeBindFailure(), is(true)); assertThat(cellFieldError(errors, cellAddress(record.positions.get("operate"))).isTypeBindFailure(), is(true)); } else if(record.no == 5) { // 空白 assertThat(cellFieldError(errors, cellAddress(record.positions.get("color"))).isTypeBindFailure(), is(true)); assertThat(cellFieldError(errors, cellAddress(record.positions.get("operate"))).isTypeBindFailure(), is(true)); } else { fail(String.format("not support test case. No=%d.", record.no)); } } private void assertRecord(final FormattedRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.color, is(Color.Red)); assertThat(record.operate, is(Operate.Refer)); } else if(record.no == 2) { // 正しい値 assertThat(record.color, is(Color.Red)); assertThat(record.operate, is(Operate.Refer)); } else if(record.no == 3) { // 不正な値 assertThat(cellFieldError(errors, cellAddress(record.positions.get("color"))).isTypeBindFailure(), is(true)); assertThat(cellFieldError(errors, cellAddress(record.positions.get("operate"))).isTypeBindFailure(), is(true)); } else if(record.no == 4) { // 小文字 assertThat(record.color, is(Color.Yellow)); assertThat(record.operate, is(Operate.Edit)); } else if(record.no == 5) { // 空白 assertThat(record.color, is(Color.Yellow)); assertThat(record.operate, is(Operate.Edit)); } else { fail(String.format("not support test case. No=%d.", record.no)); } } private void assertRecord(final FormulaRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.color, is(nullValue())); assertThat(record.operate, is(nullValue())); } else if(record.no == 2) { // 正しい値 assertThat(record.color, is(Color.Red)); assertThat(record.operate, is(Operate.Refer)); } else { fail(String.format("not support test case. No=%d.", record.no)); } } /** * 列挙型の書き込みテスト */ @Test public void test_save_enum() throws Exception { // テストデータの作成 final EnumSheet outSheet = new EnumSheet(); // アノテーションなしのデータ作成 outSheet.add(new SimpleRecord() .comment("空文字")); outSheet.add(new SimpleRecord() .color(Color.Green) .operate(Operate.Edit) .comment("値")); // アノテーションありのデータ作成 outSheet.add(new FormattedRecord() .comment("空文字")); outSheet.add(new FormattedRecord() .color(Color.Green) .operate(Operate.Edit) .comment("値")); // 数式のデータ作成 outSheet.add(new FormulaRecord().comment("空文字")); outSheet.add(new FormulaRecord().comment("R")); // ファイルへの書き込み XlsMapper mapper = new XlsMapper(); mapper.getConig().setContinueTypeBindFailure(true); File outFile = new File(OUT_DIR, "convert_enum.xlsx"); try(InputStream template = new FileInputStream("src/test/data/convert_template.xlsx"); OutputStream out = new FileOutputStream(outFile)) { mapper.save(template, out, outSheet); } // 書き込んだファイルを読み込み値の検証を行う。 try(InputStream in = new FileInputStream(outFile)) { SheetBindingErrors errors = new SheetBindingErrors(EnumSheet.class); EnumSheet sheet = mapper.load(in, EnumSheet.class, errors); if(sheet.simpleRecords != null) { assertThat(sheet.simpleRecords, hasSize(outSheet.simpleRecords.size())); for(int i=0; i < sheet.simpleRecords.size(); i++) { assertRecord(sheet.simpleRecords.get(i), outSheet.simpleRecords.get(i), errors); } } if(sheet.formattedRecords != null) { assertThat(sheet.formattedRecords, hasSize(outSheet.formattedRecords.size())); for(int i=0; i < sheet.formattedRecords.size(); i++) { assertRecord(sheet.formattedRecords.get(i), outSheet.formattedRecords.get(i), errors); } } if(sheet.formulaRecords != null) { assertThat(sheet.formulaRecords, hasSize(outSheet.formulaRecords.size())); for(int i=0; i < sheet.formulaRecords.size(); i++) { assertRecord(sheet.formulaRecords.get(i), outSheet.formulaRecords.get(i), errors); } } } } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final SimpleRecord inRecord, final SimpleRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.color, is(outRecord.color)); assertThat(inRecord.operate, is(outRecord.operate)); assertThat(inRecord.comment, is(outRecord.comment)); } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final FormattedRecord inRecord, final FormattedRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); if(inRecord.no == 1) { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.color, is(Color.Red)); assertThat(inRecord.operate, is(Operate.Refer)); assertThat(inRecord.comment, is(outRecord.comment)); } else { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.color, is(outRecord.color)); assertThat(inRecord.operate, is(outRecord.operate)); assertThat(inRecord.comment, is(outRecord.comment)); } } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final FormulaRecord inRecord, final FormulaRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); if(inRecord.no == 1) { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.color, is(nullValue())); assertThat(inRecord.operate, is(nullValue())); assertThat(inRecord.comment, is(outRecord.comment)); } else { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.color, is(Color.Red)); assertThat(inRecord.operate, is(Operate.Refer)); assertThat(inRecord.comment, is(outRecord.comment)); } } /** * 列挙型 - 単純な列挙型 */ private enum Color { Red, Green, Yellow, ; } /** * 列挙型 - メソッド、フィールドを持つ */ private enum Operate { Refer("参照"), Edit("編集"), Delete("削除"), ; private final String localeName; private Operate(String localeName) { this.localeName = localeName; } public String localeName() { return localeName; } } @XlsSheet(name="列挙型") private static class EnumSheet { @XlsHint(order=1) @XlsHorizontalRecords(tableLabel="列挙型(アノテーションなし)", terminal=RecordTerminal.Border, ignoreEmptyRecord=true, overRecord=OverRecordOperate.Insert) private List<SimpleRecord> simpleRecords; @XlsHint(order=2) @XlsHorizontalRecords(tableLabel="列挙型(初期値、書式)", terminal=RecordTerminal.Border, ignoreEmptyRecord=true, overRecord=OverRecordOperate.Insert) private List<FormattedRecord> formattedRecords; @XlsHint(order=3) @XlsHorizontalRecords(tableLabel="列挙型(数式)", terminal=RecordTerminal.Border, ignoreEmptyRecord=true, overRecord=OverRecordOperate.Insert) private List<FormulaRecord> formulaRecords; /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public EnumSheet add(SimpleRecord record) { if(simpleRecords == null) { this.simpleRecords = new ArrayList<>(); } this.simpleRecords.add(record); record.no(simpleRecords.size()); return this; } /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public EnumSheet add(FormattedRecord record) { if(formattedRecords == null) { this.formattedRecords = new ArrayList<>(); } this.formattedRecords.add(record); record.no(formattedRecords.size()); return this; } /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public EnumSheet add(FormulaRecord record) { if(formulaRecords == null) { this.formulaRecords = new ArrayList<>(); } this.formulaRecords.add(record); record.no(formulaRecords.size()); return this; } } /** * 列挙型 - アノテーションなし * */ private static class SimpleRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsColumn(columnName="Enum型(英字)1") private Color color; @XlsColumn(columnName="Enum型(英字)2") private Operate operate; @XlsColumn(columnName="備考") private String comment; @XlsIsEmpty public boolean isEmpty() { return IsEmptyBuilder.reflectionIsEmpty(this, "positions", "labels", "no"); } public SimpleRecord no(int no) { this.no = no; return this; } public SimpleRecord color(Color color) { this.color = color; return this; } public SimpleRecord operate(Operate operate) { this.operate = operate; return this; } public SimpleRecord comment(String comment) { this.comment = comment; return this; } } /** * 列挙型 - 初期値など * */ private static class FormattedRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsConverter(defaultValue="Red", trim=true) @XlsEnumConverter(ignoreCase=true) @XlsColumn(columnName="Enum型(英字)") private Color color; @XlsConverter(defaultValue="参照", trim=true) @XlsEnumConverter(ignoreCase=true, valueMethodName="localeName") @XlsColumn(columnName="Enum型(日本語)") private Operate operate; @XlsColumn(columnName="備考") private String comment; @XlsIsEmpty public boolean isEmpty() { return IsEmptyBuilder.reflectionIsEmpty(this, "positions", "labels", "no"); } public FormattedRecord no(int no) { this.no = no; return this; } public FormattedRecord color(Color color) { this.color = color; return this; } public FormattedRecord operate(Operate operate) { this.operate = operate; return this; } public FormattedRecord comment(String comment) { this.comment = comment; return this; } } /** * 列挙型 - 数式 * */ private static class FormulaRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsEnumConverter(ignoreCase=true) @XlsColumn(columnName="Enum型(英字)") @XlsFormula("IF(\\$D{rowNumber}=\"R\",\"Red\",\"\")") private Color color; @XlsEnumConverter(ignoreCase=true, valueMethodName="localeName") @XlsColumn(columnName="Enum型(日本語)") @XlsFormula("IF(\\$D{rowNumber}=\"R\",\"参照\",\"\")") private Operate operate; @XlsColumn(columnName="備考") private String comment; @XlsIsEmpty public boolean isEmpty() { return IsEmptyBuilder.reflectionIsEmpty(this, "positions", "labels", "no"); } public FormulaRecord no(int no) { this.no = no; return this; } public FormulaRecord color(Color color) { this.color = color; return this; } public FormulaRecord operate(Operate operate) { this.operate = operate; return this; } public FormulaRecord comment(String comment) { this.comment = comment; return this; } } }