View Javadoc
1   package com.github.mygreen.supercsv.io;
2   
3   import static org.assertj.core.api.Assertions.*;
4   import static org.assertj.core.api.Assertions.assertThat;
5   import static org.junit.Assert.fail;
6   
7   import java.io.File;
8   import java.io.FileInputStream;
9   import java.io.IOException;
10  import java.io.InputStreamReader;
11  import java.nio.charset.Charset;
12  import java.time.LocalDate;
13  import java.util.ArrayList;
14  import java.util.List;
15  
16  import org.junit.Before;
17  import org.junit.Test;
18  import org.supercsv.exception.SuperCsvException;
19  import org.supercsv.prefs.CsvPreference;
20  
21  import com.github.mygreen.supercsv.builder.BeanMapping;
22  import com.github.mygreen.supercsv.builder.ColumnMapping;
23  import com.github.mygreen.supercsv.builder.LazyBeanMappingFactory;
24  import com.github.mygreen.supercsv.exception.SuperCsvBindingException;
25  import com.github.mygreen.supercsv.exception.SuperCsvNoMatchColumnSizeException;
26  import com.github.mygreen.supercsv.validation.CsvExceptionConverter;
27  
28  
29  /**
30   * {@link LazyCsvAnnotationBeanReader}のテスタ
31   * 
32   * @version 2.3
33   * @since 2.1
34   * @author T.TSUCHIE
35   *
36   */
37  public class LazyCsvAnnotationBeanReaderTest {
38      
39      private CsvExceptionConverter exceptionConverter;
40      
41      /**
42       * 初期化が未実施のときのエラーメッセージ
43       */
44      private static final String MESSAGE_NOT_INIT = "見出し情報を元にした初期化が完了していません。LazyCsvAnnotationBeanReader#init() で初期化する必要があります。";
45          
46      @Before
47      public void setUp() throws Exception {
48          this.exceptionConverter = new CsvExceptionConverter();
49      }
50      
51      /**
52       * 正常系のテスト
53       */
54      @Test
55      public void testRead() throws IOException {
56          
57          File file = new File("src/test/data/test_read_lazy.csv");
58          
59          LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
60                  SampleLazyBean.class,
61                  new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
62                  CsvPreference.STANDARD_PREFERENCE);
63          csvReader.setExceptionConverter(exceptionConverter);
64          
65          List<SampleLazyBean> list = new ArrayList<>();
66          
67          final String[] expectedHeaders = new String[]{
68                  "no",
69                  "name",
70                  "生年月日",
71                  "備考"
72              };
73          
74          // read header
75          final String[] csvHeaders = csvReader.init();
76          assertThat(csvHeaders).containsExactly(expectedHeaders);
77          
78          final String[] definitionHeaders = csvReader.getDefinedHeader();
79          assertThat(definitionHeaders).containsExactly(expectedHeaders);
80          
81          SampleLazyBean bean;
82          while((bean = csvReader.read()) != null) {
83              list.add(bean);
84              
85              assertBean(bean);
86          }
87          
88          assertThat(list).hasSize(2);
89          assertThat(csvReader.getErrorMessages()).hasSize(0);
90          
91          csvReader.close();
92          
93      }
94      
95      /**
96       * 全て読み込む - 初期化は自動的う。
97       */
98      @Test
99      public void testReadAll() throws Exception {
100         
101         File file = new File("src/test/data/test_read_lazy.csv");
102         
103         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
104                 SampleLazyBean.class,
105                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
106                 CsvPreference.STANDARD_PREFERENCE);
107         csvReader.setExceptionConverter(exceptionConverter);
108         
109         List<SampleLazyBean> list = csvReader.readAll();
110         assertThat(list).hasSize(2);
111         
112         for(SampleLazyBean bean : list) {
113             assertThat(bean);
114         }
115         
116         final String[] expectedHeaders = new String[]{
117                 "no",
118                 "name",
119                 "生年月日",
120                 "備考"
121             };
122         
123         // read header
124         final String[] definitionHeaders = csvReader.getDefinedHeader();
125         assertThat(definitionHeaders).containsExactly(expectedHeaders);
126         
127         assertThat(csvReader.getErrorMessages()).hasSize(0);
128         
129         csvReader.close();
130         
131     }
132     
133     /**
134      * 全て読み込み - CSVファイルにヘッダーがない場合
135      */
136     @Test
137     public void testReadAll_noHeader() throws Exception {
138         
139         File file = new File("src/test/data/test_read_lazy_noHeader.csv");
140         
141         LazyBeanMappingFactory factory = new LazyBeanMappingFactory();
142         BeanMapping<SampleLazyBean> beanMapping = factory.create(SampleLazyBean.class);
143         
144         // ヘッダーを持たないと設定する
145         beanMapping.setHeader(false);
146         
147         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
148                 beanMapping,
149                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
150                 CsvPreference.STANDARD_PREFERENCE);
151         csvReader.setExceptionConverter(exceptionConverter);
152         
153         final String[] headers = new String[]{
154                 "no",
155                 "name",
156                 "生年月日",
157                 "備考"
158             };
159         
160         csvReader.init(headers);
161         
162         List<SampleLazyBean> list = csvReader.readAll();
163         assertThat(list).hasSize(2);
164         
165         for(SampleLazyBean bean : list) {
166             assertThat(bean);
167         }
168         
169         assertThat(csvReader.getErrorMessages()).hasSize(0);
170         
171         csvReader.close();
172         
173     }
174     
175     /**
176      * 全て読み込み- CSVファイルにヘッダーがない場合 - 初期化をしていない場合
177      */
178     @Test
179     public void testReadAll_noHeader_noInit() throws Exception {
180         
181         File file = new File("src/test/data/test_read_lazy_noHeader.csv");
182         
183         LazyBeanMappingFactory factory = new LazyBeanMappingFactory();
184         BeanMapping<SampleLazyBean> beanMapping = factory.create(SampleLazyBean.class);
185         
186         // ヘッダーを持たないと設定する
187         beanMapping.setHeader(false);
188         
189         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
190                 beanMapping,
191                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
192                 CsvPreference.STANDARD_PREFERENCE);
193         csvReader.setExceptionConverter(exceptionConverter);
194         
195         assertThatThrownBy(() -> csvReader.readAll())
196             .isInstanceOf(IllegalStateException.class)
197             .hasMessage(MESSAGE_NOT_INIT);
198         
199         csvReader.close();
200         
201     }
202     
203     /**
204      * 全件読み込み - カラムにエラーがある場合
205      */
206     @Test
207     public void testReadAll_error_column() throws Exception {
208         
209         File file = new File("src/test/data/test_read_lazy_wrong_pattern.csv");
210         
211         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
212                 SampleLazyBean.class,
213                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
214                 CsvPreference.STANDARD_PREFERENCE);
215         csvReader.setExceptionConverter(exceptionConverter);
216         
217         try {
218             List<SampleLazyBean> list = csvReader.readAll();
219         
220         } catch(Exception e) {
221             assertThat(e).isInstanceOf(SuperCsvBindingException.class);
222         }
223         
224         // convert error messages.
225         List<String> messages = csvReader.getErrorMessages();
226         assertThat(messages).hasSize(1)
227             .contains("[2行, 3列] : 項目「生年月日」の値(2000-10-01)は、日時の書式「uuuu/MM/dd」として不正です。");
228         messages.forEach(System.out::println);
229         
230         csvReader.close();
231         
232     }
233     
234     /**
235      * 全件読み込み - カラムにエラーがある場合も処理を続ける
236      */
237     @Test
238     public void testReadAll_error_continueOnError() throws Exception {
239         
240         File file = new File("src/test/data/test_read_lazy_wrong_pattern.csv");
241         
242         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
243                 SampleLazyBean.class,
244                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
245                 CsvPreference.STANDARD_PREFERENCE);
246         csvReader.setExceptionConverter(exceptionConverter);
247         
248         List<SampleLazyBean> list = csvReader.readAll(true);
249         assertThat(list).hasSize(1);
250         
251         for(SampleLazyBean bean : list) {
252             assertBean(bean);
253         }
254         
255         // convert error messages.
256         List<String> messages = csvReader.getErrorMessages();
257         assertThat(messages).hasSize(1)
258             .contains("[2行, 3列] : 項目「生年月日」の値(2000-10-01)は、日時の書式「uuuu/MM/dd」として不正です。");
259         messages.forEach(System.out::println);
260         
261         csvReader.close();
262         
263     }
264     
265     /**
266      * 初期化に失敗する場合 - Beanに定義してある情報とCSVの列数が一致しない場合
267      */
268     @Test
269     public void testInit_noMatchColumnSize() throws Exception {
270         
271         
272         File file = new File("src/test/data/test_read_lazy.csv");
273         
274         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
275                 SampleLazyBean.class,
276                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
277                 CsvPreference.STANDARD_PREFERENCE);
278         csvReader.setExceptionConverter(exceptionConverter);
279         
280         final String[] headers = new String[]{
281                 "no",
282                 "name",
283                 "生年月日",
284                 "備考",
285                 "あああ"
286             };
287         
288         assertThatThrownBy(() -> csvReader.init(headers))
289             .isInstanceOf(SuperCsvNoMatchColumnSizeException.class);
290         
291         assertThat(csvReader.getErrorMessages())
292             .hasSize(1)
293             .containsExactly("[1行] : 列数が不正です。 4列で設定すべきですが、実際には5列になっています。");
294     }
295     
296     /**
297      * 初期化に失敗する場合 - Beanに定義してある情報とCSVのヘッダーが一致しない場合
298      * @since 2.2
299      */
300     @Test
301     public void testInit_nonDeterminedColumnNumbers() throws Exception {
302         
303         File file = new File("src/test/data/test_read_lazy.csv");
304         
305         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
306                 SampleLazyBean.class,
307                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
308                 CsvPreference.STANDARD_PREFERENCE);
309         csvReader.setExceptionConverter(exceptionConverter);
310         
311         final String[] headers = new String[]{
312                 "no",
313                 "name1",
314                 "生年月日2",
315                 "備考",
316                 "あああ"
317             };
318         
319         assertThatThrownBy(() -> csvReader.init(headers))
320             .isInstanceOf(SuperCsvException.class)
321             .hasMessage("'%s' のヘッダー([no, name1, 生年月日2, 備考, あああ])において、定義しているが一致しないラベル([生年月日])があります。",
322                     SampleLazyBean.class.getName());
323         
324         assertThat(csvReader.getErrorMessages())
325             .hasSize(0);
326         
327     }
328     
329     /**
330      * 初期化が完了していない場合
331      */
332     @Test
333     public void testRead_notInit() throws Exception {
334         
335         File file = new File("src/test/data/test_read_lazy.csv");
336         
337         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
338                 SampleLazyBean.class,
339                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
340                 CsvPreference.STANDARD_PREFERENCE);
341         csvReader.setExceptionConverter(exceptionConverter);
342         
343         // readメソッド
344         assertThatThrownBy(() -> csvReader.read())
345             .isInstanceOf(IllegalStateException.class)
346             .hasMessageContaining(MESSAGE_NOT_INIT);
347         
348         // getDefinedHeaderメソッド
349         assertThatThrownBy(() -> csvReader.getDefinedHeader())
350             .isInstanceOf(IllegalStateException.class)
351             .hasMessageContaining(MESSAGE_NOT_INIT);
352         
353         // getBeanMappingメソッド
354         assertThatThrownBy(() -> csvReader.getBeanMapping())
355             .isInstanceOf(IllegalStateException.class)
356             .hasMessageContaining(MESSAGE_NOT_INIT);
357         
358     
359     }
360     
361     /**
362      * 部分的にカラムを読み込む
363      */
364     @Test
365     public void testRead_parital() throws Exception {
366         
367         File file = new File("src/test/data/test_read_lazy_partial.csv");
368         
369         LazyCsvAnnotationBeanReader<SampleLazyPartialBean> csvReader = new LazyCsvAnnotationBeanReader<>(
370                 SampleLazyPartialBean.class,
371                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
372                 CsvPreference.STANDARD_PREFERENCE);
373         csvReader.setExceptionConverter(exceptionConverter);
374         
375         List<SampleLazyPartialBean> list = new ArrayList<>();
376         
377         final String[] expectedHeaders = new String[]{
378                 "id",
379                 "名前",
380                 "誕生日",
381                 "電話番号",
382                 "住所",
383                 "有効期限",
384                 "削除フラグ",
385                 "備考"
386             };
387         
388         // read header
389         final String[] csvHeaders = csvReader.init();
390         assertThat(csvHeaders).containsExactly(expectedHeaders);
391         
392         final String[] definitionHeaders = csvReader.getDefinedHeader();
393         assertThat(definitionHeaders).containsExactly(expectedHeaders);
394         
395         {
396             // カラム情報のチェック
397             List<ColumnMapping> columnMappingList = csvReader.getBeanMapping().getColumns();
398             assertThat(columnMappingList).hasSize(8);
399             for(int i=0; i < columnMappingList.size(); i++) {
400                 int number = i+1;
401                 ColumnMapping columnMapping = columnMappingList.get(i);
402                 assertThat(columnMapping.getNumber()).isEqualTo(number);
403                 assertThat(columnMapping.getLabel()).isEqualTo(expectedHeaders[i]);
404                 assertThat(columnMapping.isDeterminedNumber()).isEqualTo(true);
405                 
406                 if(number == 1 || number == 2 || number == 6 || number == 8) {
407                     assertThat(columnMapping.isPartialized()).isEqualTo(false);
408                 } else {
409                     assertThat(columnMapping.isPartialized()).isEqualTo(true);
410                     
411                 }
412             }
413         }
414         
415         SampleLazyPartialBean bean;
416         while((bean = csvReader.read()) != null) {
417             list.add(bean);
418             
419             assertBean(bean);
420         }
421         
422         assertThat(list).hasSize(3);
423         assertThat(csvReader.getErrorMessages()).hasSize(0);
424         
425         csvReader.close();
426         
427         
428     }
429     
430     /**
431      * 固定長のカラムを読み込む
432      */
433     @Test
434     public void testRead_fixedColumn() throws IOException {
435         
436         File file = new File("src/test/data/test_read_lazy_fixedColumn.csv");
437         
438         LazyCsvAnnotationBeanReader<SampleLazyFixedColumnBean> csvReader = new LazyCsvAnnotationBeanReader<>(
439                 SampleLazyFixedColumnBean.class,
440                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
441                 CsvPreference.STANDARD_PREFERENCE);
442         csvReader.setExceptionConverter(exceptionConverter);
443         
444         List<SampleLazyFixedColumnBean> list = new ArrayList<>();
445         
446         final String[] expectedHeaders = new String[]{
447                 "   no",
448                 "誕生日____",
449                 "ユーザ名      ",
450                 "コメント            "
451             };
452         
453         // read header
454         final String[] csvHeaders = csvReader.init();
455         assertThat(csvHeaders).containsExactly(expectedHeaders);
456         
457         final String[] definitionHeaders = csvReader.getDefinedHeader();
458         assertThat(definitionHeaders).containsExactly(expectedHeaders);
459         
460         SampleLazyFixedColumnBean bean;
461         while((bean = csvReader.read()) != null) {
462             list.add(bean);
463             
464             assertBean(bean);
465         }
466         
467         assertThat(csvReader.getErrorMessages()).hasSize(0);
468         
469         csvReader.close();
470         
471     }
472     
473     /**
474      * ハンドラ指定で読み込むテスト - 正常データのみ
475      * @since 2.3
476      */
477     @Test
478     public void testRead_withHandler_normal() throws IOException {
479         
480         File file = new File("src/test/data/test_read_lazy.csv");
481         
482         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
483                 SampleLazyBean.class,
484                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
485                 CsvPreference.STANDARD_PREFERENCE);
486         csvReader.setExceptionConverter(exceptionConverter);
487         
488         List<SampleLazyBean> list = new ArrayList<>();
489         
490         // read header
491         final String[] csvHeaders = csvReader.init();
492         assertThat(csvHeaders).hasSize(4);
493         
494         while(csvReader.read(
495                 record -> {
496                     list.add(record);
497                     assertBean(record);
498                 },
499                 error -> fail(error.getMessage())) != CsvReadStatus.EOF) {
500             
501         }
502         
503         assertThat(list).hasSize(2);
504         assertThat(csvReader.getErrorMessages()).hasSize(0);
505         
506         csvReader.close();
507         
508     }
509     
510     /**
511      * Streamで読み込むテスト - 正常時
512      * @since 2.3
513      */
514     @Test
515     public void testLines_normal() throws IOException {
516         
517         File file = new File("src/test/data/test_read_lazy.csv");
518         
519         LazyCsvAnnotationBeanReader<SampleLazyBean> csvReader = new LazyCsvAnnotationBeanReader<>(
520                 SampleLazyBean.class,
521                 new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")),
522                 CsvPreference.STANDARD_PREFERENCE);
523         csvReader.setExceptionConverter(exceptionConverter);
524         
525         List<SampleLazyBean> list = new ArrayList<>();
526         
527         // read header
528         final String[] csvHeaders = csvReader.init();
529         assertThat(csvHeaders).hasSize(4);
530         
531         csvReader.lines().forEach(record -> {
532             list.add(record);
533             assertBean(record);
534         });
535         
536         assertThat(list).hasSize(2);
537         assertThat(csvReader.getErrorMessages()).hasSize(0);
538         
539         // 順番の確認
540         assertThat(list.get(0)).hasFieldOrPropertyWithValue("no", 1);
541         assertThat(list.get(1)).hasFieldOrPropertyWithValue("no", 2);
542         
543     }
544     
545     private void assertBean(final SampleLazyBean bean) {
546         
547         if(bean.getNo() == 1) {
548             assertThat(bean.getName()).isEqualTo("山田太郎");
549             assertThat(bean.getBirthday()).isEqualTo(LocalDate.of(2000, 10, 1));
550             assertThat(bean.getComment()).isEqualTo("あいうえお");
551             
552         } else if(bean.getNo() == 2) {
553             
554             assertThat(bean.getName()).isEqualTo("鈴木次郎");
555             assertThat(bean.getBirthday()).isEqualTo(LocalDate.of(2012, 1, 2));
556             assertThat(bean.getComment()).isNull();
557             
558         }
559         
560     }
561     
562     private void assertBean(final SampleLazyPartialBean bean) {
563         
564         if(bean.getId() == 1) {
565             assertThat(bean.getName()).isEqualTo("山田太郎");
566             assertThat(bean.getExpiredDate()).isEqualTo(LocalDate.of(2017, 12, 31));
567             assertThat(bean.getComment()).isEqualTo("コメント1");
568             
569         } else if(bean.getId() == 2) {
570             
571             assertThat(bean.getName()).isEqualTo("鈴木次郎");
572             assertThat(bean.getExpiredDate()).isEqualTo(LocalDate.of(2017, 12, 31));
573             assertThat(bean.getComment()).isNull();
574             
575         } else if(bean.getId() == 3) {
576             
577             assertThat(bean.getName()).isEqualTo("佐藤花子");
578             assertThat(bean.getExpiredDate()).isEqualTo(LocalDate.of(2017, 12, 31));
579             assertThat(bean.getComment()).isEqualTo("コメント3");
580             
581         }
582         
583     }
584     
585     private void assertBean(final SampleLazyFixedColumnBean bean) {
586         
587         if(bean.getNo() == 1) {
588             assertThat(bean.getUserName()).isEqualTo("山田 太郎");
589             
590             assertThat(bean.getBirthDay()).isEqualTo(LocalDate.of(1980, 1, 28));
591             
592             assertThat(bean.getComment()).isEqualTo("全ての項目に値が設定");
593             
594         } else if(bean.getNo() == 2) {
595             
596             assertThat(bean.getUserName()).isEqualTo("田中 次郎");
597             
598             assertThat(bean.getBirthDay()).isNull();
599             
600             assertThat(bean.getComment()).isEqualTo("誕生日の項目が空。");
601             
602         } else if(bean.getNo() == 3) {
603             
604             assertThat(bean.getUserName()).isEqualTo("鈴木 三郎");
605             
606             assertThat(bean.getBirthDay()).isEqualTo(LocalDate.of(2000, 3, 25));
607             
608             assertThat(bean.getComment()).isEqualTo("コメントを切落とす。あいう。");
609             
610         }
611         
612     }
613 }