View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   */
19  package org.apache.rat.document;
20  
21  import java.io.File;
22  import java.nio.file.FileSystem;
23  import java.nio.file.FileSystems;
24  
25  import org.apache.commons.lang3.tuple.Pair;
26  import org.junit.jupiter.api.Test;
27  import org.junit.jupiter.params.ParameterizedTest;
28  import org.junit.jupiter.params.provider.FieldSource;
29  
30  import static org.assertj.core.api.Assertions.assertThat;
31  import static org.assertj.core.api.Assertions.assertThatThrownBy;
32  import static org.mockito.Mockito.mock;
33  import static org.mockito.Mockito.when;
34  import static org.apache.rat.document.FSInfoTest.WINDOWS;
35  
36  /**
37   * Tests the DcoumentName.Builder class
38   */
39  public class DocumentNameBuilderTest {
40  
41      private static final DocumentName.FSInfo[] TEST_SUITE = FSInfoTest.TEST_SUITE;
42  
43      /**
44       * Validates the data in a document name matches expected data.
45       * @param documentName the document name to check.
46       * @param name the expected fully qualified name.
47       * @param shortName the name for the last segment of the name.
48       * @param baseName the name of the base document.
49       * @param root the root the document is in.
50       * @param directorySeparator the expected directory separator.
51       * @param isCaseSensitive the expected case sensitivity.
52       * @param localized the default localized name (e.g. path and file name from base name).
53       * @param localizedArg the localized name with directory separator set to '+'
54       */
55      void assertDocumentName(DocumentName documentName, String name, String shortName, String baseName, String root,
56                     String directorySeparator, Boolean isCaseSensitive, String localized, String localizedArg) {
57          assertThat(documentName.getName()).as("Invalid name").isEqualTo(name);
58          assertThat(documentName.getShortName()).as("Invalid short name").isEqualTo(shortName);
59          assertThat(documentName.getBaseName()).as("Invalid base name").isEqualTo(baseName);
60          assertThat(documentName.getRoot()).as("Invalid root").isEqualTo(root);
61          assertThat(documentName.getDirectorySeparator()).as("Invalid directory separator").isEqualTo(directorySeparator);
62          if (isCaseSensitive) {
63              assertThat(documentName.isCaseSensitive()).as("Invalid case sensitivity").isTrue();
64          } else {
65              assertThat(documentName.isCaseSensitive()).as("Invalid case sensitivity").isFalse();
66          }
67          assertThat(documentName.localized()).as("Invalid localized ").isEqualTo(localized);
68          assertThat(documentName.localized("+")).as("Invalid localized('+')").isEqualTo(localizedArg);
69      }
70  
71      /**
72       * Verifies tha the baseName is not modified when used in the builder.
73       * Base name is default root + OS name.  For example {@code C:\windows}, or {@code /unix}
74       * @param fsInfo the file system info for the test.
75       */
76      @ParameterizedTest
77      @FieldSource("TEST_SUITE")
78      void baseNamePreserved(DocumentName.FSInfo fsInfo) {
79          final String root = fsInfo.roots()[0];
80          final String baseNameStr = root + fsInfo;
81          // create a document {os name}/bar. Used to establish basename in builder.
82          final DocumentName siblingName = DocumentName.builder(fsInfo).setName("bar").setBaseName(fsInfo.toString()).build();
83  
84          // check a relative name does not change base name.
85          String nameStr = fsInfo.mkPath("foo", "baz");
86          DocumentName documentName = DocumentName.builder(siblingName).setName(nameStr).build();
87          String expected = root + fsInfo.mkPath(fsInfo.toString(), "foo", "baz");
88          assertThat(documentName.getName()).as("relative value").isEqualTo(expected);
89          assertDocumentName(documentName, expected, "baz", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
90                  fsInfo.dirSeparator() + nameStr, "+foo+baz");
91  
92          // check a fully qualified name results in the base name not being changed.
93          documentName = DocumentName.builder(siblingName).setName(expected).build();
94          assertThat(documentName.getName()).as("absolute value").isEqualTo(expected);
95          assertDocumentName(documentName, expected, "baz", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
96                  fsInfo.dirSeparator() + nameStr, "+foo+baz");
97      }
98  
99      @ParameterizedTest
100     @FieldSource("TEST_SUITE")
101     void documentNameFromFullyQualifiedNameWithBaseName(DocumentName.FSInfo fsInfo) {
102         final String root = fsInfo.roots()[0];
103         final String baseNameStr = root + fsInfo;
104         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo");
105         DocumentName documentName = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
106         assertDocumentName(documentName, fqName, "foo", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
107                 fsInfo.dirSeparator() + "foo", "+foo");
108     }
109 
110     @ParameterizedTest
111     @FieldSource("TEST_SUITE")
112     void noBaseNameThrowsException(DocumentName.FSInfo fsInfo) {
113         final String root = fsInfo.roots()[0];
114         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo");
115         DocumentName.Builder underTest = DocumentName.builder(fsInfo).setName(fqName);
116         assertThatThrownBy(underTest::build)
117                 .isInstanceOf(NullPointerException.class)
118                 .hasMessage("Basename must not be null");
119     }
120 
121     @ParameterizedTest
122     @FieldSource("TEST_SUITE")
123     void noNameThrowsException(DocumentName.FSInfo fsInfo) {
124         final String root = fsInfo.roots()[0];
125         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo");
126         DocumentName.Builder underTest = DocumentName.builder(fsInfo).setBaseName(fqName);
127         assertThatThrownBy(underTest::build)
128                 .isInstanceOf(NullPointerException.class)
129                 .hasMessage("Name must not be null");
130     }
131 
132     @Test
133     void DocumentNameFromFileSystem() {
134         FileSystem fileSystem = FileSystems.getDefault();
135         String expectedRoot = fileSystem.getRootDirectories().iterator().next().toString();
136         DocumentName documentName = DocumentName.builder(fileSystem).setBaseName("")
137                 .setName("theName.txt").build();
138         assertThat(documentName.getRoot()).isEqualTo(expectedRoot);
139         assertThat(documentName.getName()).isEqualTo(expectedRoot + "theName.txt");
140     }
141 
142     @ParameterizedTest
143     @FieldSource("TEST_SUITE")
144     void DocumentNameFromDocumentName(DocumentName.FSInfo fsInfo) {
145         final String root = fsInfo.roots()[0];
146         final String baseNameStr = root + fsInfo;
147         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo");
148         DocumentName expected = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
149 
150         DocumentName actual = DocumentName.builder(expected).build();
151         assertThat(actual).isEqualTo(expected);
152 
153         assertDocumentName(actual, fqName, "foo", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
154                 fsInfo.dirSeparator() + "foo", "+foo");
155     }
156 
157     @ParameterizedTest
158     @FieldSource("TEST_SUITE")
159     void builderOnDocumentNameWithNameSharesBaseName(DocumentName.FSInfo fsInfo) {
160         final String root = fsInfo.roots()[0];
161         final String baseNameStr = root + fsInfo;
162 
163         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo");
164         DocumentName firstName = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
165 
166         fqName = root + fsInfo.mkPath(fsInfo.toString(), "bar");
167         DocumentName actual = DocumentName.builder(firstName).setName(fqName).setBaseName(baseNameStr).build();
168 
169         assertDocumentName(actual, fqName, "bar", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
170                 fsInfo.dirSeparator() + "bar", "+bar");
171     }
172 
173     @ParameterizedTest
174     @FieldSource("TEST_SUITE")
175     void builderOnFile(DocumentName.FSInfo fsInfo) {
176         String root = fsInfo.roots()[0];
177         final String baseNameStr = root + fsInfo.mkPath(fsInfo.toString(), "foo");
178         final String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo", "bar");
179         File file = mock(File.class);
180         File parent = mock(File.class);
181         when(file.getAbsolutePath()).thenReturn(fqName);
182         when(file.getParentFile()).thenReturn(parent);
183         when(file.isDirectory()).thenReturn(false);
184         when(parent.getAbsolutePath()).thenReturn(baseNameStr);
185         when(parent.isDirectory()).thenReturn(true);
186 
187         DocumentName actual = new DocumentName.Builder(fsInfo, file).build();
188 
189         assertDocumentName(actual, fqName, "bar", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
190                 fsInfo.dirSeparator() + "bar", "+bar");
191     }
192 
193     @Test
194     void windowRootDifference() {
195         // verify that setting the root results in the entire DocumentName being re-rooted e.g. including the basename(s).
196         DocumentName.FSInfo fsInfo = WINDOWS;
197         String root = fsInfo.roots()[0];
198         String baseNameStr = root + fsInfo.mkPath(fsInfo.toString(), "foo");
199         String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo", "bar");
200         DocumentName firstName = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
201 
202         root = fsInfo.roots()[1];
203         DocumentName actual = DocumentName.builder(firstName).setRoot(root).build();
204 
205         baseNameStr = root + fsInfo.mkPath(fsInfo.toString(), "foo");
206         fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo", "bar");
207 
208         assertDocumentName(actual, fqName, "bar", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
209                 fsInfo.dirSeparator() + "bar", "+bar");
210     }
211 
212     @ParameterizedTest
213     @FieldSource("TEST_SUITE")
214     void setRootNull(DocumentName.FSInfo fsInfo) {
215         for (String root : fsInfo.roots()) {
216             String baseNameStr = root + fsInfo.mkPath(fsInfo.toString(), "foo");
217             String fqName = root + fsInfo.mkPath(fsInfo.toString(), "foo", "bar");
218             DocumentName firstName = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
219 
220             // verify setting the root to null results in relative names with a blank root set
221             DocumentName actual = DocumentName.builder(firstName).setRoot(null).build();
222 
223             assertDocumentName(actual, fqName, "bar", baseNameStr, root, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
224                     fsInfo.dirSeparator() + "bar", "+bar");
225         }
226     }
227 
228     @ParameterizedTest
229     @FieldSource("TEST_SUITE")
230     void setRootEmpty(DocumentName.FSInfo fsInfo) {
231         for (String baseRoot : fsInfo.roots()) {
232             String baseNameStr = baseRoot + fsInfo.mkPath(fsInfo.toString(), "foo");
233             String fqName = baseRoot + fsInfo.mkPath(fsInfo.toString(), "foo", "bar");
234             DocumentName firstName = DocumentName.builder(fsInfo).setName(fqName).setBaseName(baseNameStr).build();
235 
236             DocumentName actual = DocumentName.builder(firstName).setRoot("").build();
237 
238             assertDocumentName(actual, fqName, "bar", baseNameStr, baseRoot, fsInfo.dirSeparator(), fsInfo.isCaseSensitive(),
239                     fsInfo.dirSeparator() + "bar", "+bar");
240         }
241     }
242 
243     @ParameterizedTest
244     @FieldSource("TEST_SUITE")
245     void splitRootsTest(DocumentName.FSInfo fsInfo) {
246         for (String root : fsInfo.roots()) {
247             String path = fsInfo.mkPath("My", "path", "to", "a", "file.txt");
248             Pair<String, String> result = DocumentName.builder(fsInfo).splitRoot(root + path);
249             assertThat(result.getLeft()).isEqualTo(root);
250             assertThat(result.getRight()).isEqualTo(path);
251         }
252     }
253 }