1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.document;
20
21 import java.io.File;
22 import java.io.FileFilter;
23 import java.io.FilenameFilter;
24 import java.io.IOException;
25 import java.nio.file.FileSystems;
26 import java.nio.file.Path;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.stream.Stream;
33
34 import org.apache.commons.io.FileUtils;
35 import org.apache.commons.lang3.tuple.Pair;
36 import org.apache.rat.config.exclusion.ExclusionUtils;
37 import org.apache.rat.document.DocumentName.FSInfo;
38
39 import org.assertj.core.util.Files;
40 import org.junit.jupiter.api.Test;
41 import org.junit.jupiter.params.ParameterizedTest;
42 import org.junit.jupiter.params.provider.Arguments;
43 import org.junit.jupiter.params.provider.MethodSource;
44 import org.mockito.Mockito;
45
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static org.apache.rat.document.FSInfoTest.OSX;
48 import static org.apache.rat.document.FSInfoTest.UNIX;
49 import static org.apache.rat.document.FSInfoTest.WINDOWS;
50 import static org.mockito.Mockito.mock;
51 import static org.mockito.Mockito.when;
52 import static org.mockito.ArgumentMatchers.any;
53
54 public class DocumentNameTest {
55
56 public static DocumentName mkName(Path tempDir, FSInfo fsInfo) {
57 File docFile = mkFile(tempDir.toFile(), fsInfo);
58 DocumentName result = DocumentName.builder(fsInfo).setName(docFile).build();
59 DocumentName mocked = Mockito.spy(result);
60
61 String fn = result.localized(FileSystems.getDefault().getSeparator());
62 File file = tempDir.resolve(fn.substring(1)).toFile();
63 File mockedFile = mkFile(file, fsInfo);
64 when(mocked.asFile()).thenReturn(mockedFile);
65
66 assertThat(mocked.asFile()).isEqualTo(mockedFile);
67 return mocked;
68 }
69
70 private static File[] listFiles(File file, FSInfo fsInfo) {
71 File[] fileList = file.listFiles();
72 if (fileList == null) {
73 return fileList;
74 }
75 return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).toArray(File[]::new);
76 }
77
78 private static File[] listFiles(File file, FSInfo fsInfo, FileFilter filter) {
79 File[] fileList = file.listFiles();
80 if (fileList == null) {
81 return fileList;
82 }
83 return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).filter(filter::accept).toArray(File[]::new);
84 }
85
86 private static File[] listFiles(File file, FSInfo fsInfo, FilenameFilter filter) {
87 File[] fileList = file.listFiles();
88 if (fileList == null) {
89 return fileList;
90 }
91 return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).filter(x -> filter.accept(x, x.getName())).toArray(File[]::new);
92 }
93
94 public static File mkFile(final File file, final FSInfo fsInfo) {
95 File mockedFile = mock(File.class);
96 when(mockedFile.listFiles()).thenAnswer( env -> listFiles(file, fsInfo));
97 when(mockedFile.listFiles(any(FilenameFilter.class))).thenAnswer( env -> listFiles(file, fsInfo, env.getArgument(0, FilenameFilter.class)));
98 when(mockedFile.listFiles(any(FileFilter.class))).thenAnswer(env -> listFiles(file, fsInfo, env.getArgument(0, FileFilter.class)));
99 when(mockedFile.getName()).thenReturn(ExclusionUtils.convertSeparator(file.getName(), FSInfoTest.DEFAULT.dirSeparator(), fsInfo.dirSeparator()));
100 when(mockedFile.getAbsolutePath()).thenReturn(ExclusionUtils.convertSeparator(file.getAbsolutePath(), FSInfoTest.DEFAULT.dirSeparator(), fsInfo.dirSeparator()));
101 when(mockedFile.isFile()).thenAnswer(env -> file.isFile());
102 when(mockedFile.exists()).thenAnswer(emv -> file.exists());
103 when(mockedFile.isDirectory()).thenAnswer(env -> file.isDirectory());
104
105 return mockedFile;
106 }
107
108 public static DocumentName mkName(Path tempDir, DocumentName baseDir, String pth) throws IOException {
109 DocumentName result = baseDir.resolve(ExclusionUtils.convertSeparator(pth, "/", baseDir.getDirectorySeparator()));
110 DocumentName mocked = Mockito.spy(result);
111
112 String fn = result.localized(FileSystems.getDefault().getSeparator());
113 File file = tempDir.resolve(fn.substring(1)).toFile();
114 File parent = file.getParentFile();
115 if (parent.exists() && !parent.isDirectory()) {
116 parent.delete();
117 }
118 parent.mkdirs();
119 if (file.exists()) {
120 if (file.isDirectory()) {
121 FileUtils.deleteDirectory(file);
122 } else {
123 FileUtils.delete(file);
124 }
125 }
126 file.createNewFile();
127 when(mocked.asFile()).thenReturn(file);
128 return mocked;
129 }
130
131 @ParameterizedTest(name = "{index} {0} {2}")
132 @MethodSource("resolveTestData")
133 void resolveTest(String testName, DocumentName base, String toResolve, DocumentName expected) {
134 DocumentName actual = base.resolve(toResolve);
135 assertThat(actual).isEqualTo(expected);
136 }
137
138 private static Stream<Arguments> resolveTestData() {
139 List<Arguments> lst = new ArrayList<>();
140
141 DocumentName base = DocumentName.builder(UNIX).setName("/dir/unix").setBaseName("/").build();
142
143 DocumentName expected = DocumentName.builder(UNIX).setName("/dir/unix/relative").setBaseName("/").build();
144 lst.add(Arguments.of("unix", base, "relative", expected));
145
146 expected = DocumentName.builder(UNIX).setName("/from/root").setBaseName("/").build();
147 lst.add(Arguments.of("unix", base, "/from/root", expected));
148
149 expected = DocumentName.builder(UNIX).setName("dir/up/and/down").setBaseName("/").build();
150 lst.add(Arguments.of("unix", base, "../up/and/down", expected));
151
152 expected = DocumentName.builder(UNIX).setName("/from/root").setBaseName("/").build();
153 lst.add(Arguments.of("unix", base, "\\from\\root", expected));
154
155 expected = DocumentName.builder(UNIX).setName("dir/up/and/down").setBaseName("/").build();
156 lst.add(Arguments.of("unix", base, "..\\up\\and\\down", expected));
157
158
159 base = DocumentName.builder(WINDOWS).setName("\\dir\\windows").setBaseName("C:\\").build();
160
161 expected = DocumentName.builder(WINDOWS).setName("\\dir\\windows\\relative").setBaseName("C:\\").build();
162 lst.add(Arguments.of("windows", base, "relative", expected));
163
164 expected = DocumentName.builder(WINDOWS).setName("\\from\\root").setBaseName("C:\\").build();
165 lst.add(Arguments.of("windows", base, "/from/root", expected));
166
167 expected = DocumentName.builder(WINDOWS).setName("dir\\up\\and\\down").setBaseName("C:\\").build();
168 lst.add(Arguments.of("windows", base, "../up/and/down", expected));
169
170 expected = DocumentName.builder(WINDOWS).setName("\\from\\root").setBaseName("C:\\").build();
171 lst.add(Arguments.of("windows", base, "\\from\\root", expected));
172
173 expected = DocumentName.builder(WINDOWS).setName("dir\\up\\and\\down").setBaseName("C:\\").build();
174 lst.add(Arguments.of("windows", base, "..\\up\\and\\down", expected));
175
176
177 base = DocumentName.builder(OSX).setName("/dir/osx").setBaseName("/").build();
178
179 expected = DocumentName.builder(OSX).setName("/dir/osx/relative").setBaseName("/").build();
180 lst.add(Arguments.of("osx", base, "relative", expected));
181
182 expected = DocumentName.builder(OSX).setName("/from/root").setBaseName("/").build();
183 lst.add(Arguments.of("osx", base, "/from/root", expected));
184
185 expected = DocumentName.builder(OSX).setName("dir/up/and/down").setBaseName("/").build();
186 lst.add(Arguments.of("osx", base, "../up/and/down", expected));
187
188 expected = DocumentName.builder(OSX).setName("/from/root").setBaseName("/").build();
189 lst.add(Arguments.of("osx", base, "\\from\\root", expected));
190
191 expected = DocumentName.builder(OSX).setName("dir/up/and/down").setBaseName("/").build();
192 lst.add(Arguments.of("osx", base, "..\\up\\and\\down", expected));
193
194 return lst.stream();
195 }
196
197 @Test
198 void localizeTest() {
199 DocumentName documentName = DocumentName.builder(UNIX).setName("/a/b/c")
200 .setBaseName("/a").build();
201 assertThat(documentName.localized()).isEqualTo("/b/c");
202 assertThat(documentName.localized("-")).isEqualTo("-b-c");
203
204 documentName = DocumentName.builder(WINDOWS).setName("\\a\\b\\c")
205 .setBaseName("\\a").build();
206 assertThat(documentName.localized()).isEqualTo("\\b\\c");
207 assertThat(documentName.localized("-")).isEqualTo("-b-c");
208
209 documentName = DocumentName.builder(OSX).setName("/a/b/c")
210 .setBaseName("/a").build();
211 assertThat(documentName.localized()).isEqualTo("/b/c");
212 assertThat(documentName.localized("-")).isEqualTo("-b-c");
213 }
214
215 @ParameterizedTest(name = "{index} {0}")
216 @MethodSource("validBuilderData")
217 void validBuilderTest(String testName, DocumentName.Builder builder, String root, String name, String baseName, String dirSeparator) {
218 DocumentName underTest = builder.build();
219 assertThat(underTest.getRoot()).as(testName).isEqualTo(root);
220 assertThat(underTest.getDirectorySeparator()).as(testName).isEqualTo(dirSeparator);
221 assertThat(underTest.getName()).as(testName).isEqualTo(root + dirSeparator + name);
222 assertThat(underTest.getBaseName()).as(testName).isEqualTo(root + dirSeparator + baseName);
223 }
224
225 private static Stream<Arguments> validBuilderData() {
226 List<Arguments> lst = new ArrayList<>();
227 File f = Files.newTemporaryFile();
228
229 Set<String> roots = new HashSet<>();
230 File[] rootary = File.listRoots();
231 if (rootary != null) {
232 for (File root : rootary) {
233 String name = root.getPath();
234 roots.add(name);
235 }
236 }
237
238 String name = f.getAbsolutePath();
239 String root = "";
240 for (String sysRoot : roots) {
241 if (name.startsWith(sysRoot)) {
242 name = name.substring(sysRoot.length());
243 if (sysRoot.endsWith(File.separator)) {
244 root = sysRoot.substring(0, sysRoot.length() - File.separator.length());
245 }
246 break;
247 }
248 }
249
250 File p = f.getParentFile();
251 String baseName = p.getAbsolutePath().substring(root.length());
252 if (baseName.startsWith(File.separator)) {
253 baseName = baseName.substring(File.separator.length());
254 }
255 lst.add(Arguments.of("setName(file)", DocumentName.builder().setName(f), root, name, baseName, File.separator));
256 lst.add(Arguments.of("Builder(file)", DocumentName.builder(f), root, name, baseName, File.separator));
257
258 lst.add(Arguments.of("setName(dir)", DocumentName.builder().setName(p), root, baseName, baseName, File.separator));
259 lst.add(Arguments.of("Builder(dir)", DocumentName.builder(p), root, baseName, baseName, File.separator));
260
261 File r = new File(root.isEmpty() ? File.separator : root);
262 lst.add(Arguments.of("setName(root)", DocumentName.builder().setName(r), root, "", "", File.separator));
263 lst.add(Arguments.of("Builder(root)", DocumentName.builder(r), root, "", "", File.separator));
264
265
266 lst.add(Arguments.of("foo/bar foo", DocumentName.builder(UNIX)
267 .setName("/foo/bar").setBaseName("foo"), "", "foo/bar", "foo", "/"));
268
269 DocumentName.Builder builder = DocumentName.builder(WINDOWS).setName("\\foo\\bar").setBaseName("C:\\foo")
270 .setRoot("C:");
271 lst.add(Arguments.of("\\foo\\bar foo", builder, "C:", "foo\\bar", "foo", "\\"));
272
273 lst.add(Arguments.of("foo/bar foo", DocumentName.builder(OSX)
274 .setName("/foo/bar").setBaseName("foo"), "", "foo/bar", "foo", "/"));
275
276 return lst.stream();
277 }
278
279 @Test
280 void splitRootsTest() {
281 Pair<String, String> result = DocumentName.builder(WINDOWS).splitRoot("C:\\My\\path\\to\\a\\file.txt");
282 assertThat(result.getLeft()).isEqualTo("C:");
283 assertThat(result.getRight()).isEqualTo("My\\path\\to\\a\\file.txt");
284
285 result = DocumentName.builder(UNIX).splitRoot("/My/path/to/a/file.txt");
286 assertThat(result.getLeft()).isEqualTo("");
287 assertThat(result.getRight()).isEqualTo("My/path/to/a/file.txt");
288
289 result = DocumentName.builder(OSX).splitRoot("/My/path/to/a/file.txt");
290 assertThat(result.getLeft()).isEqualTo("");
291 assertThat(result.getRight()).isEqualTo("My/path/to/a/file.txt");
292 }
293
294 @Test
295 void archiveEntryNameTest() {
296 String entryName = "./anArchiveEntry.txt";
297 DocumentName archiveName = DocumentName.builder(WINDOWS)
298 .setName("C:\\archives\\anArchive.zip").setBaseName("C:\\archives").build();
299
300 assertThat(archiveName.getRoot()).isEqualTo("C:");
301 assertThat(archiveName.getDirectorySeparator()).isEqualTo("\\");
302 assertThat(archiveName.getBaseName()).isEqualTo("C:\\archives");
303 assertThat(archiveName.getName()).isEqualTo("C:\\archives\\anArchive.zip");
304 assertThat(archiveName.localized()).isEqualTo("\\anArchive.zip");
305
306 ArchiveEntryName archiveEntryName = new ArchiveEntryName(archiveName, entryName);
307
308 assertThat(archiveEntryName.getRoot()).isEqualTo(archiveName.getName()+"#");
309 assertThat(archiveEntryName.getDirectorySeparator()).isEqualTo("/");
310 assertThat(archiveEntryName.getBaseName()).isEqualTo("C:\\archives\\anArchive.zip#");
311 assertThat(archiveEntryName.getName()).isEqualTo("C:\\archives\\anArchive.zip#/anArchiveEntry.txt");
312 assertThat(archiveEntryName.localized()).isEqualTo("/anArchiveEntry.txt");
313 assertThat(archiveEntryName.localized("/")).isEqualTo("/anArchive.zip#/anArchiveEntry.txt");
314
315
316 entryName = "./someDir/anArchiveEntry.txt";
317 archiveEntryName = new ArchiveEntryName(archiveName, entryName);
318
319 assertThat(archiveEntryName.getRoot()).isEqualTo(archiveName.getName()+"#");
320 assertThat(archiveEntryName.getDirectorySeparator()).isEqualTo("/");
321 assertThat(archiveEntryName.getBaseName()).isEqualTo("C:\\archives\\anArchive.zip#");
322 assertThat(archiveEntryName.getName()).isEqualTo("C:\\archives\\anArchive.zip#/someDir/anArchiveEntry.txt");
323 assertThat(archiveEntryName.localized()).isEqualTo("/someDir/anArchiveEntry.txt");
324 assertThat(archiveEntryName.localized("/")).isEqualTo("/anArchive.zip#/someDir/anArchiveEntry.txt");
325 }
326 }