View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.monitor;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertTrue;
22  
23  import java.io.File;
24  import java.io.FileFilter;
25  import java.io.IOException;
26  import java.util.Iterator;
27  
28  import org.apache.commons.io.FileUtils;
29  import org.apache.commons.io.FilenameUtils;
30  import org.apache.commons.io.IOCase;
31  import org.apache.commons.io.comparator.NameFileComparator;
32  import org.apache.commons.io.filefilter.CanReadFileFilter;
33  import org.apache.commons.io.filefilter.FileFilterUtils;
34  import org.apache.commons.io.monitor.FileAlterationObserver.Builder;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * {@link FileAlterationObserver} Test Case.
39   */
40  class FileAlterationObserverTest extends AbstractMonitorTest {
41  
42      private static final String PATH_STRING_FIXTURE = "/foo";
43  
44      /**
45       * Constructs a new instance.
46       */
47      FileAlterationObserverTest() {
48          listener = new CollectionFileListener(true);
49      }
50  
51      /**
52       * Call {@link FileAlterationObserver#checkAndNotify()}.
53       */
54      protected void checkAndNotify() {
55          observer.checkAndNotify();
56      }
57  
58      private String directoryToUnixString(final FileAlterationObserver observer) {
59          return FilenameUtils.separatorsToUnix(observer.getDirectory().toString());
60      }
61  
62      /**
63       * Test add/remove listeners.
64       */
65      @Test
66      void testAddRemoveListeners() {
67          final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(PATH_STRING_FIXTURE).getUnchecked();
68          // Null Listener
69          observer.addListener(null);
70          assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[1]");
71          observer.removeListener(null);
72          assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[2]");
73  
74          // Add Listener
75          final FileAlterationListenerAdaptor listener = new FileAlterationListenerAdaptor();
76          observer.addListener(listener);
77          final Iterator<FileAlterationListener> it = observer.getListeners().iterator();
78          assertTrue(it.hasNext(), "Listeners[3]");
79          assertEquals(listener, it.next(), "Added");
80          assertFalse(it.hasNext(), "Listeners[4]");
81  
82          // Remove Listener
83          observer.removeListener(listener);
84          assertFalse(observer.getListeners().iterator().hasNext(), "Listeners[5]");
85      }
86  
87      @Test
88      void testBuilder_File() {
89          final File file = new File(PATH_STRING_FIXTURE);
90          final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(file).getUnchecked();
91          assertEquals(file, observer.getDirectory());
92      }
93  
94      @Test
95      void testBuilder_File_FileFilter() {
96          final File file = new File(PATH_STRING_FIXTURE);
97          // @formatter:off
98          final FileAlterationObserver observer = FileAlterationObserver.builder()
99                  .setFile(file)
100                 .setFileFilter(CanReadFileFilter.CAN_READ)
101                 .getUnchecked();
102         // @formatter:on
103         assertEquals(file, observer.getDirectory());
104         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
105     }
106 
107     @Test
108     void testBuilder_File_FileFilter_IOCase() {
109         final File file = new File(PATH_STRING_FIXTURE);
110         // @formatter:off
111         final FileAlterationObserver observer = FileAlterationObserver.builder()
112                 .setFile(file)
113                 .setFileFilter(CanReadFileFilter.CAN_READ)
114                 .setIOCase(IOCase.INSENSITIVE)
115                 .getUnchecked();
116         // @formatter:on
117         assertEquals(file, observer.getDirectory());
118         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
119         assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
120     }
121 
122     @Test
123     void testBuilder_String() {
124         final String file = PATH_STRING_FIXTURE;
125         final FileAlterationObserver observer = FileAlterationObserver.builder().setFile(file).getUnchecked();
126         assertEquals(file, directoryToUnixString(observer));
127     }
128 
129     @Test
130     void testBuilder_String_FileFilter() {
131         final String file = PATH_STRING_FIXTURE;
132         // @formatter:off
133         final FileAlterationObserver observer = FileAlterationObserver.builder()
134                 .setFile(file)
135                 .setFileFilter(CanReadFileFilter.CAN_READ)
136                 .getUnchecked();
137         // @formatter:on
138         assertEquals(file, directoryToUnixString(observer));
139         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
140     }
141 
142     @Test
143     void testBuilder_String_FileFilter_IOCase() {
144         final String file = PATH_STRING_FIXTURE;
145         // @formatter:off
146         final FileAlterationObserver observer = FileAlterationObserver.builder()
147                 .setFile(file)
148                 .setFileFilter(CanReadFileFilter.CAN_READ)
149                 .setIOCase(IOCase.INSENSITIVE)
150                 .getUnchecked();
151         // @formatter:on
152         assertEquals(file, directoryToUnixString(observer));
153         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
154         assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
155     }
156 
157     @Test
158     void testConstructor_File() {
159         final File file = new File(PATH_STRING_FIXTURE);
160         @SuppressWarnings("deprecation")
161         final FileAlterationObserver observer = new FileAlterationObserver(file);
162         assertEquals(file, observer.getDirectory());
163     }
164 
165     @Test
166     void testConstructor_File_FileFilter() {
167         final File file = new File(PATH_STRING_FIXTURE);
168         @SuppressWarnings("deprecation")
169         final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
170         assertEquals(file, observer.getDirectory());
171         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
172     }
173 
174     @Test
175     void testConstructor_File_FileFilter_IOCase() {
176         final File file = new File(PATH_STRING_FIXTURE);
177         @SuppressWarnings("deprecation")
178         final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
179         assertEquals(file, observer.getDirectory());
180         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
181         assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
182     }
183 
184     @Test
185     void testConstructor_String() {
186         final String file = PATH_STRING_FIXTURE;
187         @SuppressWarnings("deprecation")
188         final FileAlterationObserver observer = new FileAlterationObserver(file);
189         assertEquals(file, directoryToUnixString(observer));
190     }
191 
192     @Test
193     void testConstructor_String_FileFilter() {
194         final String file = PATH_STRING_FIXTURE;
195         @SuppressWarnings("deprecation")
196         final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
197         assertEquals(file, directoryToUnixString(observer));
198         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
199     }
200 
201     @Test
202     void testConstructor_String_FileFilter_IOCase() {
203         final String file = PATH_STRING_FIXTURE;
204         @SuppressWarnings("deprecation")
205         final FileAlterationObserver observer = new FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
206         assertEquals(file, directoryToUnixString(observer));
207         assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
208         assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, observer.getComparator());
209     }
210 
211     /**
212      * Tests checkAndNotify() method
213      *
214      * @throws Exception Thrown on test failure.
215      */
216     @Test
217     void testDirectory() throws Exception {
218         checkAndNotify();
219         checkCollectionsEmpty("A");
220         final File testDirA = new File(testDir, "test-dir-A");
221         final File testDirB = new File(testDir, "test-dir-B");
222         final File testDirC = new File(testDir, "test-dir-C");
223         testDirA.mkdir();
224         testDirB.mkdir();
225         testDirC.mkdir();
226         final File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
227         final File testDirAFile2 = touch(new File(testDirA, "A-file2.txt")); // filter should ignore this
228         final File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
229         File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
230         final File testDirBFile1 = touch(new File(testDirB, "B-file1.java"));
231 
232         checkAndNotify();
233         checkCollectionSizes("B", 3, 0, 0, 4, 0, 0);
234         assertTrue(listener.getCreatedDirectories().contains(testDirA), "B testDirA");
235         assertTrue(listener.getCreatedDirectories().contains(testDirB), "B testDirB");
236         assertTrue(listener.getCreatedDirectories().contains(testDirC), "B testDirC");
237         assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
238         assertFalse(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
239         assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
240         assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
241         assertTrue(listener.getCreatedFiles().contains(testDirBFile1), "B testDirBFile1");
242 
243         checkAndNotify();
244         checkCollectionsEmpty("C");
245 
246         testDirAFile4 = touch(testDirAFile4);
247         FileUtils.deleteDirectory(testDirB);
248         checkAndNotify();
249         checkCollectionSizes("D", 0, 0, 1, 0, 1, 1);
250         assertTrue(listener.getDeletedDirectories().contains(testDirB), "D testDirB");
251         assertTrue(listener.getChangedFiles().contains(testDirAFile4), "D testDirAFile4");
252         assertTrue(listener.getDeletedFiles().contains(testDirBFile1), "D testDirBFile1");
253 
254         FileUtils.deleteDirectory(testDir);
255         checkAndNotify();
256         checkCollectionSizes("E", 0, 0, 2, 0, 0, 3);
257         assertTrue(listener.getDeletedDirectories().contains(testDirA), "E testDirA");
258         assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "E testDirAFile1");
259         assertFalse(listener.getDeletedFiles().contains(testDirAFile2), "E testDirAFile2");
260         assertTrue(listener.getDeletedFiles().contains(testDirAFile3), "E testDirAFile3");
261         assertTrue(listener.getDeletedFiles().contains(testDirAFile4), "E testDirAFile4");
262 
263         testDir.mkdir();
264         checkAndNotify();
265         checkCollectionsEmpty("F");
266 
267         checkAndNotify();
268         checkCollectionsEmpty("G");
269     }
270 
271     /**
272      * Test checkAndNotify() creating
273      *
274      * @throws IOException if an I/O error occurs.
275      */
276     @Test
277     void testFileCreate() throws IOException {
278         checkAndNotify();
279         checkCollectionsEmpty("A");
280         File testDirA = new File(testDir, "test-dir-A");
281         testDirA.mkdir();
282         testDir = touch(testDir);
283         testDirA = touch(testDirA);
284         File testDirAFile1 = new File(testDirA, "A-file1.java");
285         final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
286         File testDirAFile3 = new File(testDirA, "A-file3.java");
287         final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
288         File testDirAFile5 = new File(testDirA, "A-file5.java");
289 
290         checkAndNotify();
291         checkCollectionSizes("B", 1, 0, 0, 2, 0, 0);
292         assertFalse(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
293         assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
294         assertFalse(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
295         assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
296         assertFalse(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
297 
298         assertFalse(testDirAFile1.exists(), "B testDirAFile1 exists");
299         assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
300         assertFalse(testDirAFile3.exists(), "B testDirAFile3 exists");
301         assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
302         assertFalse(testDirAFile5.exists(), "B testDirAFile5 exists");
303 
304         checkAndNotify();
305         checkCollectionsEmpty("C");
306 
307         // Create file with name < first entry
308         testDirAFile1 = touch(testDirAFile1);
309         testDirA = touch(testDirA);
310         checkAndNotify();
311         checkCollectionSizes("D", 0, 1, 0, 1, 0, 0);
312         assertTrue(testDirAFile1.exists(), "D testDirAFile1 exists");
313         assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "D testDirAFile1");
314 
315         // Create file with name between 2 entries
316         testDirAFile3 = touch(testDirAFile3);
317         testDirA = touch(testDirA);
318         checkAndNotify();
319         checkCollectionSizes("E", 0, 1, 0, 1, 0, 0);
320         assertTrue(testDirAFile3.exists(), "E testDirAFile3 exists");
321         assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "E testDirAFile3");
322 
323         // Create file with name > last entry
324         testDirAFile5 = touch(testDirAFile5);
325         testDirA = touch(testDirA);
326         checkAndNotify();
327         checkCollectionSizes("F", 0, 1, 0, 1, 0, 0);
328         assertTrue(testDirAFile5.exists(), "F testDirAFile5 exists");
329         assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "F testDirAFile5");
330     }
331 
332     /**
333      * Test checkAndNotify() deleting
334      *
335      * @throws IOException if an I/O error occurs.
336      */
337     @Test
338     void testFileDelete() throws IOException {
339         checkAndNotify();
340         checkCollectionsEmpty("A");
341         File testDirA = new File(testDir, "test-dir-A");
342         testDirA.mkdir();
343         testDir = touch(testDir);
344         testDirA = touch(testDirA);
345         final File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
346         final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
347         final File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
348         final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
349         final File testDirAFile5 = touch(new File(testDirA, "A-file5.java"));
350 
351         assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
352         assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
353         assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
354         assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
355         assertTrue(testDirAFile5.exists(), "B testDirAFile5 exists");
356 
357         checkAndNotify();
358         checkCollectionSizes("B", 1, 0, 0, 5, 0, 0);
359         assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
360         assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
361         assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
362         assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
363         assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
364 
365         checkAndNotify();
366         checkCollectionsEmpty("C");
367 
368         // Delete first entry
369         FileUtils.deleteQuietly(testDirAFile1);
370         testDirA = touch(testDirA);
371         checkAndNotify();
372         checkCollectionSizes("D", 0, 1, 0, 0, 0, 1);
373         assertFalse(testDirAFile1.exists(), "D testDirAFile1 exists");
374         assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "D testDirAFile1");
375 
376         // Delete file with name between 2 entries
377         FileUtils.deleteQuietly(testDirAFile3);
378         testDirA = touch(testDirA);
379         checkAndNotify();
380         checkCollectionSizes("E", 0, 1, 0, 0, 0, 1);
381         assertFalse(testDirAFile3.exists(), "E testDirAFile3 exists");
382         assertTrue(listener.getDeletedFiles().contains(testDirAFile3), "E testDirAFile3");
383 
384         // Delete last entry
385         FileUtils.deleteQuietly(testDirAFile5);
386         testDirA = touch(testDirA);
387         checkAndNotify();
388         checkCollectionSizes("F", 0, 1, 0, 0, 0, 1);
389         assertFalse(testDirAFile5.exists(), "F testDirAFile5 exists");
390         assertTrue(listener.getDeletedFiles().contains(testDirAFile5), "F testDirAFile5");
391     }
392 
393     /**
394      * Test checkAndNotify() creating
395      *
396      * @throws IOException if an I/O error occurs.
397      */
398     @Test
399     void testFileUpdate() throws IOException {
400         checkAndNotify();
401         checkCollectionsEmpty("A");
402         File testDirA = new File(testDir, "test-dir-A");
403         testDirA.mkdir();
404         testDir = touch(testDir);
405         testDirA = touch(testDirA);
406         File testDirAFile1 = touch(new File(testDirA, "A-file1.java"));
407         final File testDirAFile2 = touch(new File(testDirA, "A-file2.java"));
408         File testDirAFile3 = touch(new File(testDirA, "A-file3.java"));
409         final File testDirAFile4 = touch(new File(testDirA, "A-file4.java"));
410         File testDirAFile5 = touch(new File(testDirA, "A-file5.java"));
411 
412         checkAndNotify();
413         checkCollectionSizes("B", 1, 0, 0, 5, 0, 0);
414         assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "B testDirAFile1");
415         assertTrue(listener.getCreatedFiles().contains(testDirAFile2), "B testDirAFile2");
416         assertTrue(listener.getCreatedFiles().contains(testDirAFile3), "B testDirAFile3");
417         assertTrue(listener.getCreatedFiles().contains(testDirAFile4), "B testDirAFile4");
418         assertTrue(listener.getCreatedFiles().contains(testDirAFile5), "B testDirAFile5");
419 
420         assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
421         assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
422         assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
423         assertTrue(testDirAFile4.exists(), "B testDirAFile4 exists");
424         assertTrue(testDirAFile5.exists(), "B testDirAFile5 exists");
425 
426         checkAndNotify();
427         checkCollectionsEmpty("C");
428 
429         // Update first entry
430         testDirAFile1 = touch(testDirAFile1);
431         testDirA = touch(testDirA);
432         checkAndNotify();
433         checkCollectionSizes("D", 0, 1, 0, 0, 1, 0);
434         assertTrue(listener.getChangedFiles().contains(testDirAFile1), "D testDirAFile1");
435 
436         // Update file with name between 2 entries
437         testDirAFile3 = touch(testDirAFile3);
438         testDirA = touch(testDirA);
439         checkAndNotify();
440         checkCollectionSizes("E", 0, 1, 0, 0, 1, 0);
441         assertTrue(listener.getChangedFiles().contains(testDirAFile3), "E testDirAFile3");
442 
443         // Update last entry
444         testDirAFile5 = touch(testDirAFile5);
445         testDirA = touch(testDirA);
446         checkAndNotify();
447         checkCollectionSizes("F", 0, 1, 0, 0, 1, 0);
448         assertTrue(listener.getChangedFiles().contains(testDirAFile5), "F testDirAFile5");
449     }
450 
451     /**
452      * Test checkAndNotify() method
453      *
454      * @throws IOException if an I/O error occurs.
455      */
456     @Test
457     void testObserveSingleFile() throws IOException {
458         final File testDirA = new File(testDir, "test-dir-A");
459         File testDirAFile1 = new File(testDirA, "A-file1.java");
460         testDirA.mkdir();
461 
462         final FileFilter nameFilter = FileFilterUtils.nameFileFilter(testDirAFile1.getName());
463         createObserver(testDirA, nameFilter);
464         checkAndNotify();
465         checkCollectionsEmpty("A");
466         assertFalse(testDirAFile1.exists(), "A testDirAFile1 exists");
467 
468         // Create
469         testDirAFile1 = touch(testDirAFile1);
470         File testDirAFile2 = touch(new File(testDirA, "A-file2.txt")); /* filter should ignore */
471         File testDirAFile3 = touch(new File(testDirA, "A-file3.java")); /* filter should ignore */
472         assertTrue(testDirAFile1.exists(), "B testDirAFile1 exists");
473         assertTrue(testDirAFile2.exists(), "B testDirAFile2 exists");
474         assertTrue(testDirAFile3.exists(), "B testDirAFile3 exists");
475         checkAndNotify();
476         checkCollectionSizes("C", 0, 0, 0, 1, 0, 0);
477         assertTrue(listener.getCreatedFiles().contains(testDirAFile1), "C created");
478         assertFalse(listener.getCreatedFiles().contains(testDirAFile2), "C created");
479         assertFalse(listener.getCreatedFiles().contains(testDirAFile3), "C created");
480 
481         // Modify
482         testDirAFile1 = touch(testDirAFile1);
483         testDirAFile2 = touch(testDirAFile2);
484         testDirAFile3 = touch(testDirAFile3);
485         checkAndNotify();
486         checkCollectionSizes("D", 0, 0, 0, 0, 1, 0);
487         assertTrue(listener.getChangedFiles().contains(testDirAFile1), "D changed");
488         assertFalse(listener.getChangedFiles().contains(testDirAFile2), "D changed");
489         assertFalse(listener.getChangedFiles().contains(testDirAFile3), "D changed");
490 
491         // Delete
492         FileUtils.deleteQuietly(testDirAFile1);
493         FileUtils.deleteQuietly(testDirAFile2);
494         FileUtils.deleteQuietly(testDirAFile3);
495         assertFalse(testDirAFile1.exists(), "E testDirAFile1 exists");
496         assertFalse(testDirAFile2.exists(), "E testDirAFile2 exists");
497         assertFalse(testDirAFile3.exists(), "E testDirAFile3 exists");
498         checkAndNotify();
499         checkCollectionSizes("E", 0, 0, 0, 0, 0, 1);
500         assertTrue(listener.getDeletedFiles().contains(testDirAFile1), "E deleted");
501         assertFalse(listener.getDeletedFiles().contains(testDirAFile2), "E deleted");
502         assertFalse(listener.getDeletedFiles().contains(testDirAFile3), "E deleted");
503     }
504 
505     /**
506      * Test toString().
507      */
508     @Test
509     void testToString() {
510         final File file = new File(PATH_STRING_FIXTURE);
511         final Builder builder = FileAlterationObserver.builder();
512         FileAlterationObserver observer = builder.setFile(file).getUnchecked();
513         assertEquals("FileAlterationObserver[file='" + file.getPath() + "', true, listeners=0]", observer.toString());
514         observer = builder.setFileFilter(CanReadFileFilter.CAN_READ).getUnchecked();
515         assertEquals("FileAlterationObserver[file='" + file.getPath() + "', CanReadFileFilter, listeners=0]", observer.toString());
516         assertEquals(file, observer.getDirectory());
517     }
518 }