View Javadoc
1   package com.opencsv.bean;
2   
3   import com.opencsv.bean.mocks.FuzzyMock;
4   import com.opencsv.bean.mocks.MockBean;
5   import com.opencsv.exceptions.CsvException;
6   import org.apache.commons.collections4.MultiValuedMap;
7   import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
8   import org.junit.jupiter.api.Test;
9   
10  import java.io.StringReader;
11  import java.io.StringWriter;
12  import java.util.Arrays;
13  import java.util.List;
14  
15  import static org.junit.jupiter.api.Assertions.*;
16  
17  /**
18   * Tests {@link FuzzyMappingStrategy}.
19   * @author Andrew Rucker Jones
20   */
21  public class FuzzyMappingTest {
22  
23      private static final String HEADER_FRAGMENT = "integerHeader,splitIntegerHeader,joinedIntegerHeader,joinedIntegerHeader,booleanHeader,integer header,split integer header,joined integer header,boolean header,exactMatch";
24      private static final String HEADERS = HEADER_FRAGMENT + ",this header name has nothing to do with the member it matches\n";
25      private static final String INCOMPLETE_HEADERS = HEADER_FRAGMENT + "\n";
26      private static final String EXACT_DATA = "exact works";
27      private static final String WILD_DATA = "wildly inexact works";
28      private static final String DATA_FRAGMENT = "1,2 3,4,5,wahr,6,7,8,false," + EXACT_DATA;
29      private static final String DATA = DATA_FRAGMENT + "," + WILD_DATA + "\n";
30      private static final String INCOMPLETE_DATA = DATA_FRAGMENT + "\n";
31  
32      private void testAllButWildlyInexact(FuzzyMock bean) {
33          assertEquals(1, bean.getIntHeader());
34          assertEquals(Arrays.asList(2, 3), bean.getSplitIntHeaders());
35          assertEquals(Arrays.asList(4, 5), bean.getJoinedIntHeaders().get("joinedIntegerHeader"));
36          assertTrue(bean.getBoolHeader());
37          assertEquals(6, bean.getIntegerHeader());
38          assertEquals(7, bean.getSplitIntegerHeader());
39          assertEquals(8, bean.getJoinedIntegerHeader());
40          assertFalse(bean.isBooleanHeader());
41          assertEquals(EXACT_DATA, bean.getExactMatch());
42      }
43  
44      @Test
45      public void testReadingFuzzyWithoutAnnotations() {
46          MappingStrategy<MockBean> strategy = new FuzzyMappingStrategy<>();
47          strategy.setType(MockBean.class);
48          StringReader input = new StringReader("name,ident,order number,number,double number\nAndrew,myID,12J,1,2.3\n");
49          List<MockBean> beans = new CsvToBeanBuilder<MockBean>(input)
50                  .withMappingStrategy(strategy)
51                  .build().parse();
52          assertNotNull(beans);
53          assertEquals(1, beans.size());
54          MockBean bean = beans.get(0);
55          assertEquals("Andrew", bean.getName());
56          assertEquals("myID", bean.getId());
57          assertEquals("12J", bean.getOrderNumber());
58          assertEquals(1, bean.getNum());
59          assertEquals(2.3, bean.getDoubleNum());
60      }
61  
62      /**
63       * Tests reading with {@link FuzzyMappingStrategy} and some annotations present.
64       * <p>Also incidentally tests:<ul>
65       *     <li>Precedence of explicit annotations (all name-based types)</li>
66       *     <li>Exact matches between header names and member variable names</li>
67       *     <li>Inexact but close matches between header names and variable names</li>
68       *     <li>Wildly inexact matches between header names and variable names</li>
69       *     <li>All headers and all member variables consumed in matching</li>
70       * </ul></p>
71       */
72      @Test
73      public void testReadingFuzzyWithAnnotationsWithBuilder() {
74          MappingStrategy<FuzzyMock> strategy = new FuzzyMappingStrategyBuilder<FuzzyMock>()
75                  .withType(FuzzyMock.class)
76                  .build();
77          StringReader input = new StringReader(HEADERS + DATA);
78          List<FuzzyMock> beans = new CsvToBeanBuilder<FuzzyMock>(input)
79                  .withMappingStrategy(strategy)
80                  .build().parse();
81          assertNotNull(beans);
82          assertEquals(1, beans.size());
83          FuzzyMock bean = beans.get(0);
84          testAllButWildlyInexact(bean);
85          assertEquals(WILD_DATA, bean.getWildlyInexactMatch());
86      }
87  
88      /**
89       * Tests reading with {@link FuzzyMappingStrategy} and some annotations present.
90       * <p>Also incidentally tests:<ul>
91       * <li>Precedence of explicit annotations (all name-based types)</li>
92       * <li>Exact matches between header names and member variable names</li>
93       * <li>Inexact but close matches between header names and variable names</li>
94       * <li>Wildly inexact matches between header names and variable names</li>
95       * <li>All headers and all member variables consumed in matching</li>
96       * </ul></p>
97       */
98      @Test
99      public void testReadingFuzzyWithAnnotationsWithSetType() {
100         MappingStrategy<FuzzyMock> strategy = new FuzzyMappingStrategyBuilder<FuzzyMock>().build();
101         strategy.setType(FuzzyMock.class);
102         StringReader input = new StringReader(HEADERS + DATA);
103         List<FuzzyMock> beans = new CsvToBeanBuilder<FuzzyMock>(input)
104                 .withMappingStrategy(strategy)
105                 .build().parse();
106         assertNotNull(beans);
107         assertEquals(1, beans.size());
108         FuzzyMock bean = beans.get(0);
109         testAllButWildlyInexact(bean);
110         assertEquals(WILD_DATA, bean.getWildlyInexactMatch());
111     }
112 
113     @Test
114     public void testHeadersUnmatched() {
115         MappingStrategy<FuzzyMock> strategy = new FuzzyMappingStrategyBuilder<FuzzyMock>()
116                 .withForceCorrectRecordLength(true)
117                 .build();
118         strategy.setType(FuzzyMock.class);
119         final String data = "potentially unmatched data";
120         StringReader input = new StringReader("potentially unmatched header," + HEADERS + data + "," + DATA);
121         List<FuzzyMock> beans = new CsvToBeanBuilder<FuzzyMock>(input)
122                 .withMappingStrategy(strategy)
123                 .build().parse();
124         assertNotNull(beans);
125         assertEquals(1, beans.size());
126         FuzzyMock bean = beans.get(0);
127         testAllButWildlyInexact(bean);
128         assertTrue(WILD_DATA.equals(bean.getWildlyInexactMatch()) ^ data.equals(bean.getWildlyInexactMatch()));
129     }
130 
131     @Test
132     public void testVariablesUnmatched() {
133         MappingStrategy<FuzzyMock> strategy = new FuzzyMappingStrategy<>();
134         strategy.setType(FuzzyMock.class);
135         StringReader input = new StringReader(INCOMPLETE_HEADERS + INCOMPLETE_DATA);
136         List<FuzzyMock> beans = new CsvToBeanBuilder<FuzzyMock>(input)
137                 .withMappingStrategy(strategy)
138                 .build().parse();
139         assertNotNull(beans);
140         assertEquals(1, beans.size());
141         FuzzyMock bean = beans.get(0);
142         testAllButWildlyInexact(bean);
143         assertNull(bean.getWildlyInexactMatch());
144     }
145 
146     @Test
147     public void testWritingFuzzy() throws CsvException {
148         FuzzyMock bean = new FuzzyMock();
149         bean.setBooleanHeader(true);
150         bean.setBoolHeader(Boolean.FALSE);
151         bean.setExactMatch(EXACT_DATA);
152         bean.setIntegerHeader(1);
153         bean.setIntHeader(2);
154         bean.setJoinedIntegerHeader(3);
155         MultiValuedMap<String, Integer> map = new ArrayListValuedHashMap<>();
156         map.put("joinedIntegerHeader", 4);
157         map.put("joinedIntegerHeader", 5);
158         bean.setJoinedIntHeaders(map);
159         bean.setSplitIntegerHeader(6);
160         bean.setSplitIntHeaders(Arrays.asList(7, 8));
161         bean.setWildlyInexactMatch(WILD_DATA);
162         StringWriter output = new StringWriter();
163         MappingStrategy<FuzzyMock> strategy = new FuzzyMappingStrategy<>();
164         strategy.setType(FuzzyMock.class);
165         new StatefulBeanToCsvBuilder<FuzzyMock>(output)
166                 .withMappingStrategy(strategy)
167                 .withApplyQuotesToAll(false)
168                 .build().write(bean);
169         assertEquals("BOOLEANHEADER,INTEGERHEADER,SPLITINTEGERHEADER,joinedIntegerHeader,joinedIntegerHeader\n" +
170                 "falsch,2,7 8,4,5\n", output.toString()); // Because nothing else is annotated
171     }
172 }