1 package com.opencsv.validators;
2
3 import com.opencsv.exceptions.CsvValidationException;
4 import org.junit.jupiter.api.Assertions;
5 import org.junit.jupiter.api.DisplayName;
6 import org.junit.jupiter.api.Test;
7
8 import java.util.function.Function;
9
10 import static org.junit.jupiter.api.Assertions.assertFalse;
11 import static org.junit.jupiter.api.Assertions.assertTrue;
12
13 public class RowFunctionValidatorTest {
14 private static final String[] GOOD_ROW = {"8675309", "Firstname", "M", "Lastname", "Dec 06, 1951"};
15 private static final String[] BAD_ROW = {"not a number", "not capitalized", "not an initial", "Not Single word", "12/06/51"};
16 private static final String[] LONG_ROW = {"8675309", "Firstname", "M", "Lastname", "Dec 06, 1951", "More data"};
17 private static final String[] SHORT_ROW = {"8675309", "Firstname", "Lastname", "Dec 06, 1951"};
18 private static final String[] EMPTY_ROW = {};
19 private static final String FAILURE_MESSAGE = "The first element of the row must be a number!";
20
21 private RowValidator validator;
22 private static final Function<String[], Boolean> FIRST_ELEMENT_IS_A_NUMBER =
23 (x) -> x[0].matches("^[0-9]+$");
24 private static final RowValidator FIRST_ELEMENT_VALIDATOR = new RowFunctionValidator(FIRST_ELEMENT_IS_A_NUMBER, FAILURE_MESSAGE);
25
26 private static final Function<String[], Boolean> SECOND_ELEMENT_IS_SIMPLE_NAME =
27 (x) -> x[1].matches("^[A-Z]+([a-z]*)*$");
28
29 private static final Function<String[], Boolean> THIRD_ELEMENT_IS_MIDDLE_INITIAL =
30 (x) -> x[2].matches("^[A-Z]$");
31
32 private static final Function<String[], Boolean> FOURTH_ELEMENT_IS_SIMPLE_NAME =
33 (x) -> x[3].matches("^[A-Z]+([a-z]*)*$");
34
35 private static final Function<String[], Boolean> FIFTH_ELEMENT_IS_SPECIFIC_DATE_FORMAT =
36 (x) -> x[4].matches("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s+(0?[1-9]|[1-2][0-9]|3[01]),\\s*(19[0-9]{2}|[2-9][0-9]{3}|[0-9]{2})$");
37
38 private static final Function<String[], Boolean> ROW_MUST_HAVE_FIVE_ELEMENTS =
39 (x) -> (x.length == 5);
40
41 @Test
42 @DisplayName("isValid with a function to ensure that the first element is a number.")
43 public void functionTestNumberIsValid() {
44 assertTrue(FIRST_ELEMENT_VALIDATOR.isValid(GOOD_ROW));
45 assertFalse(FIRST_ELEMENT_VALIDATOR.isValid(BAD_ROW));
46 }
47
48 @Test
49 @DisplayName("validate with a function to ensure that the first element is a number.")
50 public void functionTestNumberValidate() {
51 Assertions.assertDoesNotThrow(() -> FIRST_ELEMENT_VALIDATOR.validate(GOOD_ROW));
52 Assertions.assertEquals(FAILURE_MESSAGE,
53 Assertions.assertThrows(CsvValidationException.class, () -> FIRST_ELEMENT_VALIDATOR.validate(BAD_ROW)).getMessage()
54 );
55 }
56
57 @Test
58 @DisplayName("null String array is considered invalid")
59 public void nullArrayIsInvalid() {
60 assertFalse(FIRST_ELEMENT_VALIDATOR.isValid(null));
61 }
62
63 @Test
64 @DisplayName("An empty String array is considered invalid")
65 public void AnEmptyArrayIsInvalid() {
66 assertFalse(FIRST_ELEMENT_VALIDATOR.isValid(EMPTY_ROW));
67 }
68
69 @Test
70 @DisplayName("Simple test to show checking a name")
71 public void secondElementIsTheFirstName() {
72 validator = new RowFunctionValidator(SECOND_ELEMENT_IS_SIMPLE_NAME, "The second element must be the capitalized first name.");
73
74 assertTrue(validator.isValid(GOOD_ROW));
75 assertFalse(validator.isValid(BAD_ROW));
76 }
77
78 @Test
79 @DisplayName("Simple test to show checking an middle initial")
80 public void thirdElementIsMiddleInitial() {
81 validator = new RowFunctionValidator(THIRD_ELEMENT_IS_MIDDLE_INITIAL, "The third element must be the middle initial.");
82
83 assertTrue(validator.isValid(GOOD_ROW));
84 assertFalse(validator.isValid(BAD_ROW));
85 }
86
87 @Test
88 @DisplayName("Fourth element is also a name")
89 public void fourthElementIsLastName() {
90 validator = new RowFunctionValidator(FOURTH_ELEMENT_IS_SIMPLE_NAME, "The fourth element must be the capitalized last name.");
91
92 assertTrue(validator.isValid(GOOD_ROW));
93 assertFalse(validator.isValid(BAD_ROW));
94 }
95
96 @Test
97 @DisplayName("Fifth element is a very specific date format")
98 public void fifthElementIsADate() {
99 validator = new RowFunctionValidator(FIFTH_ELEMENT_IS_SPECIFIC_DATE_FORMAT, "The fifth element must be a date with the MMM dd, yyyy format.");
100
101 assertTrue(validator.isValid(GOOD_ROW));
102 assertFalse(validator.isValid(BAD_ROW));
103 }
104
105 @Test
106 @DisplayName("The row must have a specific number of elements in order to be valid.")
107 public void numberOfElementsInARow() {
108 validator = new RowFunctionValidator(ROW_MUST_HAVE_FIVE_ELEMENTS, "A Row can have only five elements.");
109
110 assertTrue(validator.isValid(GOOD_ROW));
111 assertFalse(validator.isValid(LONG_ROW));
112 assertFalse(validator.isValid(SHORT_ROW));
113 }
114 }