1   /*
2    * Copyright (c) 1998, 2005 Gargoyle Software Inc. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    *
7    * 1. Redistributions of source code must retain the above copyright notice,
8    *    this list of conditions and the following disclaimer.
9    * 2. Redistributions in binary form must reproduce the above copyright notice,
10   *    this list of conditions and the following disclaimer in the documentation
11   *    and/or other materials provided with the distribution.
12   * 3. The end-user documentation included with the redistribution, if any, must
13   *    include the following acknowledgment:
14   *
15   *       "This product includes software developed by Gargoyle Software Inc.
16   *        (http://www.GargoyleSoftware.com/)."
17   *
18   *    Alternately, this acknowledgment may appear in the software itself, if
19   *    and wherever such third-party acknowledgments normally appear.
20   * 4. The name "Gargoyle Software" must not be used to endorse or promote
21   *    products derived from this software without prior written permission.
22   *    For written permission, please contact info@GargoyleSoftware.com.
23   * 5. Products derived from this software may not be called "GSBase", nor may
24   *    "GSBase" appear in their name, without prior written permission of
25   *    Gargoyle Software Inc.
26   *
27   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30   * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   */
38  package com.gargoylesoftware.base.util;
39  
40  import java.io.File;
41  import java.io.FileFilter;
42  import java.io.FileOutputStream;
43  import java.io.IOException;
44  import java.util.ArrayList;
45  import java.util.Collection;
46  import java.util.HashSet;
47  import java.util.Iterator;
48  import junit.framework.TestCase;
49  
50  /***
51   *  Tests For DirectoryWalker
52   *
53   * @version  $Revision: 1.6 $
54   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
55   */
56  public class DirectoryWalkerTest extends TestCase {
57  
58      private final String dirA_;
59      private final String dirB_;
60      private final String dirC_;
61      private final String dirD_;
62      private final String dirRoot_;
63      private final String fileA1_;
64      private final String fileA2_;
65      private final String fileB_;
66      private final String fileD_;
67  
68  
69      /***
70       *  Instantiate the test
71       *
72       * @param  name The name of the test
73       */
74      public DirectoryWalkerTest( final String name ) {
75          super( name );
76  
77          final String sep = File.separator;
78  
79          dirA_ = "directorywalker" + sep + "dira";
80          dirB_ = "directorywalker" + sep + "dira" + sep + "dirb";
81          dirC_ = "directorywalker" + sep + "dirc";
82          dirD_ = "directorywalker" + sep + "dirc" + sep + "dird";
83          dirRoot_ = "directorywalker";
84          fileA1_ = "directorywalker" + sep + "dira" + sep + "filea1";
85          fileA2_ = "directorywalker" + sep + "dira" + sep + "filea2";
86          fileB_ = "directorywalker" + sep + "dira" + sep + "dirb" + sep + "fileb";
87          fileD_ = "directorywalker" + sep + "dirc" + sep + "dird" + sep + "filed";
88      }
89  
90  
91  
92      /***
93       *  The JUnit setup method
94       *
95       * @exception  IOException If an error occurs
96       */
97      public void setUp()
98          throws IOException {
99  
100         createDir( dirRoot_ );
101         createDir( dirA_ );
102         createDir( dirB_ );
103         createDir( dirC_ );
104         createDir( dirD_ );
105 
106         createFile( fileA1_ );
107         createFile( fileA2_ );
108         createFile( fileB_ );
109         createFile( fileD_ );
110     }
111 
112 
113     /***
114      *  The teardown method for JUnit
115      *
116      * @exception  IOException If an error occurs
117      */
118     public void tearDown()
119         throws IOException {
120 
121         delete( fileB_ );
122         delete( dirB_ );
123         delete( fileA1_ );
124         delete( fileA2_ );
125         delete( dirA_ );
126         delete( fileD_ );
127         delete( dirD_ );
128         delete( dirC_ );
129         delete( dirRoot_ );
130     }
131 
132 
133     /***
134      *  Test the constructor with a null starting directory
135      */
136     public void testConstructor_Null() {
137         try {
138             new DirectoryWalker( null );
139             fail( "expected exception" );
140         }
141         catch( final NullPointerException e ) {
142             // Expected path
143         }
144     }
145 
146 
147     /***
148      *  Test the constructor with an empty string as a starting directory
149      */
150     public void testConstructor_Empty() {
151         try {
152             new DirectoryWalker( "" );
153             fail( "expected exception" );
154         }
155         catch( final IllegalArgumentException e ) {
156             // Expected path
157         }
158     }
159 
160 
161     /***
162      *  Test the good case for getFiles()
163      *
164      * @exception  Exception If an error occurs
165      */
166     public void testGetFiles()
167         throws Exception {
168         final Collection expectedValues = new HashSet( 7 );
169         expectedValues.add( new File( fileB_ ) );
170         expectedValues.add( new File( fileD_ ) );
171         expectedValues.add( new File( fileA1_ ) );
172         expectedValues.add( new File( fileA2_ ) );
173 
174         final DirectoryWalker walker = new DirectoryWalker( dirRoot_ );
175         final FileFilter filter = new AcceptAllFilter();
176         assertCollectionsEqual( expectedValues, walker.getFiles( filter ) );
177     }
178 
179 
180     /***
181      *  Test the good case for getDirectories()
182      *
183      * @exception  Exception If an error occurs
184      */
185     public void testGetDirectories()
186         throws Exception {
187         final Collection expectedValues = new HashSet( 7 );
188         expectedValues.add( new File( dirA_ ) );
189         expectedValues.add( new File( dirB_ ) );
190         expectedValues.add( new File( dirC_ ) );
191         expectedValues.add( new File( dirD_ ) );
192         expectedValues.add( new File( dirRoot_ ) );
193 
194         final DirectoryWalker walker = new DirectoryWalker( dirRoot_ );
195         final FileFilter filter = new AcceptAllFilter();
196         assertCollectionsEqual( expectedValues, walker.getDirectories( filter ) );
197     }
198 
199 
200     /***
201      *  Test the good path of getFilesAndDirectories()
202      *
203      * @exception  Exception If an error occurs
204      */
205     public void testGetFilesAndDirectories()
206         throws Exception {
207 
208         final Collection expectedValues = new HashSet( 11 );
209         expectedValues.add( new File( dirA_ ) );
210         expectedValues.add( new File( dirB_ ) );
211         expectedValues.add( new File( dirC_ ) );
212         expectedValues.add( new File( dirD_ ) );
213         expectedValues.add( new File( dirRoot_ ) );
214         expectedValues.add( new File( fileB_ ) );
215         expectedValues.add( new File( fileD_ ) );
216         expectedValues.add( new File( fileA1_ ) );
217         expectedValues.add( new File( fileA2_ ) );
218 
219         final DirectoryWalker walker = new DirectoryWalker( dirRoot_ );
220         final FileFilter filter = new AcceptAllFilter();
221         assertCollectionsEqual( expectedValues, walker.getFilesAndDirectories( filter ) );
222     }
223 
224 
225     /***
226      *  Test the constructor with a file rather than a directory
227      */
228     public void testConstructor_File() {
229         try {
230             new DirectoryWalker( fileA1_ );
231             fail( "expected exception" );
232         }
233         catch( final IllegalArgumentException e ) {
234             // Expected path
235         }
236     }
237 
238 
239     /***
240      *  Test the constructor with a directory that doesn't exist
241      */
242     public void testConstructor_Exists() {
243         try {
244             new DirectoryWalker( "foo_file" );
245             fail( "expected exception" );
246         }
247         catch( final IllegalArgumentException e ) {
248             // Expected path
249         }
250     }
251 
252 
253     private void delete( final String path )
254         throws IOException {
255 
256         final File file = new File( path );
257         if( file.delete() == false ) {
258             throw new IOException( "Unable to delete [" + path + "] in tearDown()" );
259         }
260     }
261 
262 
263     private void createDir( final String path )
264         throws IOException {
265 
266         if( new File( path ).mkdir() == false ) {
267             throw new IOException( "Unable to create dir [" + path + "] in setUp()" );
268         }
269     }
270 
271 
272     private void createFile( final String filename )
273         throws IOException {
274         final FileOutputStream stream = new FileOutputStream( filename );
275         stream.write( 'a' );
276         stream.close();
277     }
278 
279 
280     private void assertCollectionsEqual( final Collection expected, final Collection actual ) {
281         if( expected == null ) {
282             fail( "expected was null" );
283         }
284         if( actual == null ) {
285             fail( "actual was null" );
286         }
287 
288         final Collection actualCopy = new ArrayList( actual );
289 
290         Object object;
291         final Iterator iterator = expected.iterator();
292         while( iterator.hasNext() ) {
293             object = iterator.next();
294             if( actualCopy.remove( object ) == false ) {
295                 fail( "Object [" + object + "] found in expected but not in actual.  Actual=" + actual );
296             }
297         }
298 
299         if( actualCopy.isEmpty() == false ) {
300             fail( "more objects in actual than in expected.  Extras are: " + actualCopy );
301         }
302     }
303 
304 
305     private class AcceptAllFilter implements FileFilter {
306     		/*** @inheritDoc FileFilter#accept(File) */
307         public boolean accept( final File file ) {
308             return true;
309         }
310     }
311 }
312