1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.cli;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.math.BigDecimal;
29 import java.math.BigInteger;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.nio.file.InvalidPathException;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.text.DateFormat;
36 import java.text.SimpleDateFormat;
37 import java.time.Instant;
38 import java.util.ArrayList;
39 import java.util.Date;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.stream.Stream;
43
44 import org.apache.commons.io.FileUtils;
45 import org.apache.commons.io.IOUtils;
46 import org.junit.jupiter.api.Test;
47 import org.junit.jupiter.params.ParameterizedTest;
48 import org.junit.jupiter.params.provider.Arguments;
49 import org.junit.jupiter.params.provider.MethodSource;
50 import org.junitpioneer.jupiter.DefaultLocale;
51
52 class TypeHandlerTest {
53
54
55 public static class Instantiable {
56
57 @Override
58 public boolean equals(final Object arg0) {
59 return arg0 instanceof Instantiable;
60 }
61
62 @Override
63 public int hashCode() {
64 return 1;
65 }
66 }
67
68
69 public static final class NotInstantiable {
70 private NotInstantiable() {
71 }
72
73 }
74
75
76 private static final Converter<Path, InvalidPathException> PATH_CONVERTER = s -> Paths.get("foo");
77
78 private static Stream<Date> createDateFixtures() {
79 return Stream.of(Date.from(Instant.EPOCH), Date.from(Instant.ofEpochSecond(0)), Date.from(Instant.ofEpochSecond(40_000)));
80
81 }
82
83 private static Stream<Arguments> createValueTestParameters() throws MalformedURLException {
84
85 @SuppressWarnings("unused")
86 final Class<?> loadStatic = PatternOptionBuilder.FILES_VALUE;
87
88
89 final List<Arguments> list = new ArrayList<>();
90
91
92
93
94
95 final Date date = new Date(1023400137000L);
96 final DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
97
98 list.add(Arguments.of(Instantiable.class.getName(), PatternOptionBuilder.CLASS_VALUE, Instantiable.class));
99 list.add(Arguments.of("what ever", PatternOptionBuilder.CLASS_VALUE, ParseException.class));
100
101 list.add(Arguments.of("what ever", PatternOptionBuilder.DATE_VALUE, ParseException.class));
102 list.add(Arguments.of(dateFormat.format(date), PatternOptionBuilder.DATE_VALUE, date));
103 list.add(Arguments.of("Jun 06 17:48:57 EDT 2002", PatternOptionBuilder.DATE_VALUE, ParseException.class));
104
105 list.add(Arguments.of("non-existing.file", PatternOptionBuilder.EXISTING_FILE_VALUE, ParseException.class));
106
107 list.add(Arguments.of("some-file.txt", PatternOptionBuilder.FILE_VALUE, new File("some-file.txt")));
108
109 list.add(Arguments.of("some-path.txt", Path.class, new File("some-path.txt").toPath()));
110
111
112 list.add(Arguments.of("some.files", PatternOptionBuilder.FILES_VALUE, "some.files"));
113
114 list.add(Arguments.of("just-a-string", Integer.class, ParseException.class));
115 list.add(Arguments.of("5", Integer.class, 5));
116 list.add(Arguments.of("5.5", Integer.class, ParseException.class));
117 list.add(Arguments.of(Long.toString(Long.MAX_VALUE), Integer.class, ParseException.class));
118
119 list.add(Arguments.of("just-a-string", Long.class, ParseException.class));
120 list.add(Arguments.of("5", Long.class, 5L));
121 list.add(Arguments.of("5.5", Long.class, ParseException.class));
122
123 list.add(Arguments.of("just-a-string", Short.class, ParseException.class));
124 list.add(Arguments.of("5", Short.class, (short) 5));
125 list.add(Arguments.of("5.5", Short.class, ParseException.class));
126 list.add(Arguments.of(Integer.toString(Integer.MAX_VALUE), Short.class, ParseException.class));
127
128 list.add(Arguments.of("just-a-string", Byte.class, ParseException.class));
129 list.add(Arguments.of("5", Byte.class, (byte) 5));
130 list.add(Arguments.of("5.5", Byte.class, ParseException.class));
131 list.add(Arguments.of(Short.toString(Short.MAX_VALUE), Byte.class, ParseException.class));
132
133 list.add(Arguments.of("just-a-string", Character.class, 'j'));
134 list.add(Arguments.of("5", Character.class, '5'));
135 list.add(Arguments.of("5.5", Character.class, '5'));
136 list.add(Arguments.of("\\u0124", Character.class, Character.toChars(0x0124)[0]));
137
138 list.add(Arguments.of("just-a-string", Double.class, ParseException.class));
139 list.add(Arguments.of("5", Double.class, 5d));
140 list.add(Arguments.of("5.5", Double.class, 5.5));
141
142 list.add(Arguments.of("just-a-string", Float.class, ParseException.class));
143 list.add(Arguments.of("5", Float.class, 5f));
144 list.add(Arguments.of("5.5", Float.class, 5.5f));
145 list.add(Arguments.of(Double.toString(Double.MAX_VALUE), Float.class, Float.POSITIVE_INFINITY));
146
147 list.add(Arguments.of("just-a-string", BigInteger.class, ParseException.class));
148 list.add(Arguments.of("5", BigInteger.class, new BigInteger("5")));
149 list.add(Arguments.of("5.5", BigInteger.class, ParseException.class));
150
151 list.add(Arguments.of("just-a-string", BigDecimal.class, ParseException.class));
152 list.add(Arguments.of("5", BigDecimal.class, new BigDecimal("5")));
153 list.add(Arguments.of("5.5", BigDecimal.class, new BigDecimal(5.5)));
154
155 list.add(Arguments.of("1.5", PatternOptionBuilder.NUMBER_VALUE, Double.valueOf(1.5)));
156 list.add(Arguments.of("15", PatternOptionBuilder.NUMBER_VALUE, Long.valueOf(15)));
157 list.add(Arguments.of("not a number", PatternOptionBuilder.NUMBER_VALUE, ParseException.class));
158
159 list.add(Arguments.of(Instantiable.class.getName(), PatternOptionBuilder.OBJECT_VALUE, new Instantiable()));
160 list.add(Arguments.of(NotInstantiable.class.getName(), PatternOptionBuilder.OBJECT_VALUE, ParseException.class));
161 list.add(Arguments.of("unknown", PatternOptionBuilder.OBJECT_VALUE, ParseException.class));
162
163 list.add(Arguments.of("String", PatternOptionBuilder.STRING_VALUE, "String"));
164
165 final String urlString = "https://commons.apache.org";
166 list.add(Arguments.of(urlString, PatternOptionBuilder.URL_VALUE, new URL(urlString)));
167 list.add(Arguments.of("Malformed-url", PatternOptionBuilder.URL_VALUE, ParseException.class));
168
169 return list.stream();
170
171 }
172
173 @Test
174 void testCreateClass() throws ParseException {
175 final Class<?> cls = getClass();
176 assertEquals(cls, TypeHandler.createClass(cls.getName()));
177 }
178
179 @ParameterizedTest
180 @MethodSource("createDateFixtures")
181 @DefaultLocale(language = "en", country = "US")
182 void testCreateDate(final Date date) {
183 assertEquals(date, TypeHandler.createDate(date.toString()));
184 }
185
186 @Test
187 void testCreateFile() {
188 final File file = FileUtils.current().getAbsoluteFile();
189 assertEquals(file, TypeHandler.createFile(file.toString()));
190 }
191
192 @Test
193 void testCreateFiles() {
194 assertThrows(UnsupportedOperationException.class, () -> TypeHandler.createFiles(null));
195 }
196
197 @Test
198 void testCreateNumber() throws ParseException {
199 assertEquals(0L, TypeHandler.createNumber("0"));
200 assertEquals(0d, TypeHandler.createNumber("0.0"));
201 }
202
203 @Test
204 void testCreateObject() throws ParseException {
205 assertTrue(TypeHandler.createObject(Date.class.getName()) instanceof Date);
206 }
207
208 @Test
209 void testCreateURL() throws ParseException, MalformedURLException {
210 final URL file = Paths.get("").toAbsolutePath().toUri().toURL();
211 assertEquals(file, TypeHandler.createURL(file.toString()));
212 }
213
214 @SuppressWarnings("unchecked")
215 @ParameterizedTest(name = "{0} as {1}")
216 @MethodSource("createValueTestParameters")
217 void testCreateValue(final String str, final Class<?> type, final Object expected) throws Exception {
218 @SuppressWarnings("cast")
219 final Object objectApiTest = type;
220 if (expected instanceof Class<?> && Throwable.class.isAssignableFrom((Class<?>) expected)) {
221 assertThrows((Class<Throwable>) expected, () -> TypeHandler.createValue(str, type));
222 assertThrows((Class<Throwable>) expected, () -> TypeHandler.createValue(str, objectApiTest));
223 } else {
224 assertEquals(expected, TypeHandler.createValue(str, type));
225 assertEquals(expected, TypeHandler.createValue(str, objectApiTest));
226 }
227 }
228
229 @Test
230 void testCreateValueExistingFile() throws Exception {
231 try (FileInputStream result = TypeHandler.createValue("src/test/resources/org/apache/commons/cli/existing-readable.file",
232 PatternOptionBuilder.EXISTING_FILE_VALUE)) {
233 assertNotNull(result);
234 }
235 }
236
237
238 @Test
239 void testnstantiableEquals() {
240 assertEquals(new Instantiable(), new Instantiable());
241 }
242
243 @Test
244 void testOpenFile() throws ParseException, IOException {
245 try (FileInputStream fis = TypeHandler.openFile("src/test/resources/org/apache/commons/cli/existing-readable.file")) {
246 IOUtils.consume(fis);
247 }
248 }
249
250 @Test
251 void testRegister() {
252 final Map<Class<?>, Converter<?, ? extends Throwable>> map = TypeHandler.createDefaultMap();
253 final TypeHandler typeHandler = new TypeHandler(map);
254 assertEquals(Converter.PATH, typeHandler.getConverter(Path.class));
255 try {
256 map.put(Path.class, PATH_CONVERTER);
257 assertEquals(PATH_CONVERTER, typeHandler.getConverter(Path.class));
258 } finally {
259 map.remove(Path.class);
260 assertEquals(Converter.DEFAULT, typeHandler.getConverter(Path.class));
261 }
262 }
263
264 }