EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [FileToolsTest.java]

nameclass, %method, %block, %line, %
FileToolsTest.java100% (1/1)100% (35/35)82%  (1326/1611)86%  (235.1/272)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FileToolsTest100% (1/1)100% (35/35)82%  (1326/1611)86%  (235.1/272)
testListFilesRecursively (): void 100% (1/1)19%  (25/129)27%  (5.1/19)
testFailedCopyFile (): void 100% (1/1)27%  (10/37)36%  (4/11)
testObtainBrokenComicFormat (): void 100% (1/1)35%  (11/31)50%  (4/8)
createFile (File, byte []): void 100% (1/1)45%  (25/55)75%  (7.5/10)
testSortSmart (String [], String []): void 100% (1/1)51%  (27/53)71%  (4.3/6)
testDelete (): void 100% (1/1)66%  (51/77)70%  (9.7/14)
testGetWithoutLastSuffix (String, String): void 100% (1/1)68%  (17/25)80%  (4/5)
testPortableFileNames (String, String): void 100% (1/1)68%  (17/25)80%  (4/5)
testCreateTempDir (): void 100% (1/1)69%  (31/45)94%  (6.6/7)
setUp (): void 100% (1/1)75%  (15/20)95%  (4.8/5)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
createRandomData (int): byte [] 100% (1/1)81%  (17/21)90%  (4.5/5)
testWriteLines (String, String []): void 100% (1/1)86%  (31/36)98%  (5.9/6)
testCopyFile (): void 100% (1/1)94%  (73/78)100% (16.9/17)
FileToolsTest (): void 100% (1/1)100% (3/3)100% (1/1)
createFileArray (String []): File [] 100% (1/1)100% (23/23)100% (4/4)
getFlattenedFolderNames (String []): Map 100% (1/1)100% (19/19)100% (4/4)
logFlattenedFolderNames (Map): void 100% (1/1)100% (35/35)100% (8/8)
testCopyDir (): void 100% (1/1)100% (88/88)100% (18/18)
testGetAdjustedComicFile (): void 100% (1/1)100% (21/21)100% (6/6)
testGetAdjustedComicFile (String, String): void 100% (1/1)100% (21/21)100% (6/6)
testGetFlattenedFolderNames (): void 100% (1/1)100% (215/215)100% (19/19)
testGetFolderMap (): void 100% (1/1)100% (91/91)100% (21/21)
testGetFolderNames (): void 100% (1/1)100% (96/96)100% (22/22)
testGetHomeDir (): void 100% (1/1)100% (5/5)100% (2/2)
testGetIcon (): void 100% (1/1)100% (15/15)100% (3/3)
testGetRelativePath (): void 100% (1/1)100% (14/14)100% (3/3)
testGetWithoutLastSuffix (): void 100% (1/1)100% (21/21)100% (6/6)
testObtainComicFormat (): void 100% (1/1)100% (13/13)100% (4/4)
testObtainComicFormat (String, String): void 100% (1/1)100% (15/15)100% (4/4)
testPortableFileNames (): void 100% (1/1)100% (25/25)100% (7/7)
testSortSmart (): void 100% (1/1)100% (141/141)100% (7/7)
testSortSmartSeparatedDoublePage (): void 100% (1/1)100% (31/31)100% (2/2)
testSortWithFrontPage (): void 100% (1/1)100% (31/31)100% (2/2)
testWriteLines (): void 100% (1/1)100% (41/41)100% (5/5)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.io.File;
19import java.io.FileInputStream;
20import java.io.FileOutputStream;
21import java.io.IOException;
22import java.util.Iterator;
23import java.util.Map;
24import java.util.Random;
25 
26import junit.framework.TestCase;
27import net.sf.wraplog.Logger;
28 
29/**
30 *  TestCase for FileTools.
31 *
32 * @author    Thomas Aglassinger
33 */
34public class FileToolsTest extends TestCase
35{
36    /**
37     *  Size of automatically created test files in byte.
38     */
39    private static final int TEST_FILE_SIZE = 123456;
40 
41    private FileTools fileTools;
42    private Logger logger;
43    private TestTools testTools;
44 
45    protected void setUp()
46        throws Exception {
47        super.setUp();
48        logger = Logger.getLogger(FileToolsTest.class);
49        testTools = TestTools.instance();
50        fileTools = FileTools.instance();
51    }
52 
53    private Map getFlattenedFolderNames(String[] filePaths) {
54        Map folderMap = fileTools.getFolderMap(createFileArray(filePaths));
55        Map folderNames = fileTools.getFolderNames(folderMap);
56        Map result = fileTools.getFlattenedFolderNames(folderNames);
57 
58        return result;
59    }
60 
61    public void testCopyDir()
62        throws IOException {
63        File rootDir = testTools.getTestInputFile("testCopyDir");
64        File targetDir = testTools.getTestOutputFile("testCopyDir");
65        File someSubDir = new File(rootDir, "subDir");
66        File emptySubDir = new File(rootDir, "emptyDir");
67        File fileInRootDir = new File(rootDir, "fileInRootDir.txt");
68        File fileInSubDir = new File(someSubDir, "fileInSubDir.txt");
69        byte[] manyData = createRandomData(TEST_FILE_SIZE);
70        byte[] fewData = createRandomData(1);
71 
72        // Create test data.
73        fileTools.mkdirs(targetDir);
74        fileTools.mkdirs(rootDir);
75        fileTools.mkdirs(someSubDir);
76        fileTools.mkdirs(emptySubDir);
77        createFile(fileInRootDir, fewData);
78        createFile(fileInSubDir, manyData);
79 
80        fileTools.copyDir(rootDir, targetDir);
81        // TODO: Compare directory structure and all file contents.
82 
83        // Clean up.
84        fileTools.attemptToDeleteAll(rootDir, logger);
85        fileTools.attemptToDeleteAll(targetDir, logger);
86    }
87 
88    public void testCopyFile()
89        throws IOException {
90        File source = testTools.getTestGeneratedInputFile("testCopyFile.source");
91        File target = testTools.getTestOutputFile("testCopyFile.target");
92        byte[] sourceData = createRandomData(TEST_FILE_SIZE);
93 
94        createFile(source, sourceData);
95        fileTools.copyFile(source, target);
96 
97        assertEquals("target.length", source.length(), target.length());
98 
99        byte[] targetData = new byte[TEST_FILE_SIZE];
100        FileInputStream in = new FileInputStream(target);
101 
102        try {
103            in.read(targetData);
104            testTools.assertEquals(sourceData, targetData);
105 
106            int c = in.read();
107 
108            assertEquals("target file must have ended already: " + target.getAbsolutePath(), -1, c);
109        } finally {
110            in.close();
111        }
112        fileTools.delete(target);
113        fileTools.delete(source);
114    }
115 
116    public void testCreateTempDir()
117        throws IOException {
118        File tempDir = fileTools.createTempDir(FileToolsTest.class.getName() + "-");
119 
120        try {
121            assertNotNull(tempDir);
122            assertTrue(tempDir.exists());
123            assertTrue(tempDir.isDirectory());
124        } finally {
125            fileTools.attemptToDeleteAll(tempDir, logger);
126        }
127    }
128 
129    public void testDelete()
130        throws IOException {
131        String testFileName = testTools.getTestFileName(FileToolsTest.class, "testDelete", null, "tmp");
132        File file = testTools.getTestOutputFile(testFileName);
133 
134        // test failed delete
135        if (file.exists()) {
136            throw new IllegalStateException("file must be deleted before test can run: " + file);
137        }
138        try {
139            fileTools.delete(file);
140            assertTrue("delete() of non-existent file must throw IOException", false);
141        } catch (IOException expectedError) {
142            logger.debug("cannot delete non-existent file as expected", expectedError);
143        }
144 
145        // test proper delete
146        byte[] data = createRandomData(TEST_FILE_SIZE);
147 
148        createFile(file, data);
149        fileTools.delete(file);
150        assertTrue("file must have been deleted: " + file, !file.exists());
151    }
152 
153    public void testFailedCopyFile() {
154        File testSourceFile = testTools.getTestImageFile();
155        File testTargetDir = testTools.getTestOutputFile("non-existent-dir");
156        File testTargetFile = new File(testTargetDir, testSourceFile.getName());
157 
158        assertFalse(testTargetDir.exists());
159        try {
160            fileTools.copyFile(testSourceFile, testTargetFile);
161            fail("copy to non-existent directory must fail");
162        } catch (IOException error) {
163            logger.debug("ignore expected error", error);
164        }
165        assertFalse(testTargetFile.exists());
166    }
167 
168    public void testGetAdjustedComicFile()
169        throws IOException {
170        testGetAdjustedComicFile(TestTools.TEST_COMIC_CBR, "cbr");
171        testGetAdjustedComicFile(TestTools.TEST_COMIC_CBZ, "cbz");
172        testGetAdjustedComicFile(TestTools.TEST_COMIC_PDF, "pdf");
173        testGetAdjustedComicFile(TestTools.DISGUISED_RAR, "cbr");
174        testGetAdjustedComicFile(TestTools.DISGUISED_ZIP, "cbz");
175    }
176 
177    public void testGetFlattenedFolderNames() {
178        String sep = File.separator;
179        String[] filePaths;
180        Map flattenedFolderNames;
181 
182        // Test without name clash.
183        filePaths = new String[]{
184                "hugo.png",
185                "issue_01" + sep + "01.png",
186                "issue_01" + sep + "02.png",
187                "issue_01" + sep + "03.png",
188                "issue_02" + sep + "01.png",
189                "issue_02" + sep + "02-03.png",
190                "issue_02" + sep + "04.png",
191                };
192        flattenedFolderNames = getFlattenedFolderNames(filePaths);
193        logFlattenedFolderNames(flattenedFolderNames);
194        assertNotNull(flattenedFolderNames);
195        assertTrue(flattenedFolderNames.containsKey(FileTools.NO_FOLDER_NAME));
196        assertTrue(flattenedFolderNames.containsKey("issue_01"));
197        assertTrue(flattenedFolderNames.containsKey("issue_02"));
198        assertEquals(3, flattenedFolderNames.keySet().size());
199 
200        // Test with name clash.
201        filePaths = new String[]{
202                "hugo" + sep + "issue_01" + sep + "hugo.png",
203                "sepp" + sep + "issue_01" + sep + "sepp.png",
204                "sepp" + sep + "issue_02" + sep + "sepp2.png",
205                "resi" + sep + "issue_01" + sep + "resi.png",
206                };
207        flattenedFolderNames = getFlattenedFolderNames(filePaths);
208        logFlattenedFolderNames(flattenedFolderNames);
209        assertNotNull(flattenedFolderNames);
210        assertTrue(flattenedFolderNames.containsKey("issue_01"));
211        assertTrue(flattenedFolderNames.containsKey("issue_01_1"));
212        assertTrue(flattenedFolderNames.containsKey("issue_01_2"));
213        assertTrue(flattenedFolderNames.containsKey("issue_02"));
214        assertEquals(4, flattenedFolderNames.keySet().size());
215    }
216 
217    public void testGetFolderMap()
218        throws IOException {
219        // Create test data.
220        File rootFolder = testTools.getTestInputFile("testGetFolderMap");
221        File someSubFolder = new File(rootFolder, "subFolder");
222        File emptySubFolder = new File(rootFolder, "emptyFolder");
223        File fileInRootFolder = new File(rootFolder, "fileInRootFolder.txt");
224        File fileInSubFolder = new File(someSubFolder, "fileInSubFolder.txt");
225        byte[] manyData = createRandomData(TEST_FILE_SIZE);
226        byte[] fewData = createRandomData(1);
227 
228        fileTools.mkdirs(rootFolder);
229        fileTools.mkdirs(someSubFolder);
230        fileTools.mkdirs(emptySubFolder);
231        createFile(fileInRootFolder, fewData);
232        createFile(fileInSubFolder, manyData);
233 
234        // Perform test.
235        Map folderMap = fileTools.getFolderMap(rootFolder);
236        String emptyFolderPath = emptySubFolder.getPath();
237        String someSubFolderPath = someSubFolder.getPath();
238 
239        assertNotNull(folderMap);
240        assertFalse(folderMap.isEmpty());
241        assertFalse(folderMap.containsKey(emptyFolderPath));
242        assertTrue(folderMap.containsKey(someSubFolderPath));
243 
244        // Clean up.
245        fileTools.attemptToDeleteAll(rootFolder, logger);
246    }
247 
248    public void testGetFolderNames()
249        throws IOException {
250        // Create test data.
251        File rootFolder = testTools.getTestInputFile("testGetFolderNames");
252        File someSubFolder = new File(rootFolder, "subFolder");
253        File emptySubFolder = new File(rootFolder, "emptyFolder");
254        File fileInRootFolder = new File(rootFolder, "fileInRootFolder.txt");
255        File fileInSubFolder = new File(someSubFolder, "fileInSubFolder.txt");
256        byte[] manyData = createRandomData(TEST_FILE_SIZE);
257        byte[] fewData = createRandomData(1);
258 
259        fileTools.mkdirs(rootFolder);
260        fileTools.mkdirs(someSubFolder);
261        fileTools.mkdirs(emptySubFolder);
262        createFile(fileInRootFolder, fewData);
263        createFile(fileInSubFolder, manyData);
264 
265        // Perform test.
266        Map folderMap = fileTools.getFolderMap(rootFolder);
267        Map folderNames = fileTools.getFolderNames(folderMap);
268        String emptyFolderName = emptySubFolder.getName();
269        String someSubFolderName = someSubFolder.getName();
270 
271        assertNotNull(folderNames);
272        assertFalse(folderNames.isEmpty());
273        assertFalse(folderNames.containsKey(emptyFolderName));
274        assertTrue(folderNames.containsKey(someSubFolderName));
275 
276        // Clean up.
277        fileTools.attemptToDeleteAll(rootFolder, logger);
278    }
279 
280    public void testGetHomeDir() {
281        assertNotNull(fileTools.getHomeDir());
282    }
283 
284    public void testGetIcon() {
285        assertNotNull(fileTools.getIconFor(testTools.getTestComicFile()));
286        assertNotNull(fileTools.getIconFor(testTools.getTestGeneratedInputDir()));
287    }
288 
289    public void testGetRelativePath() {
290        File testFile = testTools.getTestComicFile();
291 
292        assertEquals(testFile.getName(), fileTools.getRelativePath(testFile.getParentFile(), testFile));
293    }
294 
295    public void testGetWithoutLastSuffix() {
296        testGetWithoutLastSuffix("hugo", "hugo");
297        testGetWithoutLastSuffix("hugo.tar", "hugo");
298        testGetWithoutLastSuffix("hugo.tar.gz", "hugo.tar");
299        testGetWithoutLastSuffix(".", "");
300        testGetWithoutLastSuffix("", "");
301    }
302 
303    public void testListFilesRecursively()
304        throws IOException {
305        File tempDir = fileTools.createTempDir(
306                FileToolsTest.class.getName() + ".testListFilesRecursively-");
307        File[] noFiles = fileTools.listFilesRecursively(tempDir);
308 
309        assertEquals(0, noFiles.length);
310 
311        // Create a nested directory structure with 2 files in it.
312        File nestedDir = new File(new File(new File(tempDir, "a"), "b"), "c");
313 
314        fileTools.mkdirs(nestedDir);
315        fileTools.copyFile(testTools.getTestGeneratedInputFile(TestTools.SINGLE_PAGE_COMIC),
316                new File(tempDir, "a.tmp"));
317        fileTools.copyFile(testTools.getTestGeneratedInputFile(TestTools.SINGLE_PAGE_COMIC),
318                new File(nestedDir, "b.tmp"));
319        fileTools.mkdirs(new File(nestedDir, "c.dir"));
320 
321        File[] twoFiles = fileTools.listFilesRecursively(tempDir);
322 
323        assertEquals(2, twoFiles.length);
324 
325        // Test error handling.
326        try {
327            File nonExistentFolder = new File(nestedDir, "must_not_exist");
328 
329            fileTools.listFilesRecursively(nonExistentFolder);
330            fail("folder must not be listed: " + nonExistentFolder.getAbsolutePath());
331        } catch (TunneledIOException expectedError) {
332            if (logger.isDebugEnabled()) {
333                logger.debug("ignore expected error", expectedError);
334            }
335        }
336 
337        // Clean up.
338        fileTools.attemptToDeleteAll(tempDir, logger);
339    }
340 
341    public void testObtainBrokenComicFormat() {
342        File comicFile = testTools.getTestFile(TestTools.TEST_TEXT_NAME);
343 
344        try {
345            String comicFormat = fileTools.obtainComicFormat(comicFile);
346 
347            fail("comic format must not be detected but was: " + comicFormat);
348        } catch (IOException expectedError) {
349            if (logger.isDebugEnabled()) {
350                logger.debug("ignore expected error", expectedError);
351            }
352        }
353    }
354 
355    public void testObtainComicFormat()
356        throws IOException {
357        testObtainComicFormat(FileTools.FORMAT_PDF, TestTools.TEST_COMIC_PDF);
358        testObtainComicFormat(FileTools.FORMAT_RAR, TestTools.TEST_COMIC_CBR);
359        testObtainComicFormat(FileTools.FORMAT_ZIP, TestTools.TEST_COMIC_CBZ);
360    }
361 
362    public void testPortableFileNames() {
363        testPortableFileNames("hugo.txt", "hugo.txt");
364        testPortableFileNames("h?go.txt", "h-go.txt");
365        testPortableFileNames("???.txt", "-.txt");
366        testPortableFileNames("a--b", "a-b");
367        testPortableFileNames("?-b", "-b");
368        testPortableFileNames("", "");
369    }
370 
371    public void testPortableFileNames(String name, String expected) {
372        assert name != null;
373        assert expected != null;
374 
375        String actual = fileTools.getPortableFileName(name);
376 
377        assertEquals(expected, actual);
378    }
379 
380    public void testSortSmart() {
381        testSortSmart(new String[]{}, new String[]{});
382        testSortSmart(new String[]{"p/n01.s", "p/n0203.s", "p/n04.s"}, new String[]{"p/n01.s", "p/n0203.s", "p/n04.s"});
383        testSortSmart(new String[]{"p/n1.s", "p/n2.s"}, new String[]{"p/n1.s", "p/n2.s"});
384        testSortSmart(new String[]{"p/n2.s", "p/n1.s"}, new String[]{"p/n1.s", "p/n2.s"});
385        testSortSmart(new String[]{"p/n01.s", "p/n0203.s", "p/n04.s"}, new String[]{"p/n01.s", "p/n0203.s", "p/n04.s"});
386        testSortSmart(new String[]{"p/n01.s", "p/n02+03.s", "p/n04.s"},
387                new String[]{"p/n01.s", "p/n02+03.s", "p/n04.s"});
388    }
389 
390    public void testSortSmartSeparatedDoublePage() {
391        testSortSmart(new String[]{"p/n1.s", "p/n2-3.s", "p/n4.s"}, new String[]{"p/n1.s", "p/n2-3.s", "p/n4.s"});
392    }
393 
394    public void testSortWithFrontPage() {
395        testSortSmart(new String[]{"p/n1.s", "p/n0front.s", "p/n2.s"}, new String[]{"p/n0front.s", "p/n1.s", "p/n2.s"});
396    }
397 
398    public void testWriteLines()
399        throws IOException {
400        testWriteLines("empty", new String[]{});
401        testWriteLines("oneEmptyLine", new String[]{""});
402        testWriteLines("oneLine", new String[]{"one"});
403        testWriteLines("someLines", new String[]{"one", "two", "three four five"});
404    }
405 
406    private void createFile(File source, byte[] data)
407        throws IOException {
408        assert source != null;
409        assert data != null;
410        FileOutputStream out = new FileOutputStream(source);
411        boolean written = false;
412 
413        try {
414            out.write(data);
415            written = true;
416        } finally {
417            out.close();
418            if (!written) {
419                fileTools.deleteOrWarn(source, logger);
420            }
421        }
422    }
423 
424    private File[] createFileArray(String[] filePaths) {
425        File[] result = new File[filePaths.length];
426 
427        for (int i = 0; i < filePaths.length; i += 1) {
428            result[i] = new File(filePaths[i]);
429        }
430        return result;
431    }
432 
433    private byte[] createRandomData(int size) {
434        assert size > 0;
435        byte[] data = new byte[size];
436        Random randomizer = new Random(0);
437 
438        randomizer.nextBytes(data);
439        return data;
440    }
441 
442    private void logFlattenedFolderNames(Map flattenedFolderNames) {
443        Iterator rider = flattenedFolderNames.keySet().iterator();
444 
445        while (rider.hasNext()) {
446            String name = (String) rider.next();
447            File folder = (File) flattenedFolderNames.get(name);
448 
449            if (logger.isInfoEnabled()) {
450                logger.info(name + " <- " + folder);
451            }
452        }
453    }
454 
455    private void testGetAdjustedComicFile(String fileName, String expectedSuffix)
456        throws IOException {
457        File comicFile = testTools.getTestFile(fileName);
458        File adjustedComicFile = fileTools.getAdjustedComicFile(comicFile);
459 
460        assertNotNull(adjustedComicFile);
461 
462        String adjustedSuffix = fileTools.getSuffix(adjustedComicFile);
463 
464        assertEquals(expectedSuffix, adjustedSuffix);
465    }
466 
467    private void testGetWithoutLastSuffix(String fileName, String expected) {
468        assert fileName != null;
469        assert expected != null;
470        String actual = fileTools.getWithoutLastSuffix(fileName);
471 
472        assertEquals(expected, actual);
473    }
474 
475    private void testObtainComicFormat(String expectedFormat, String testComicName)
476        throws IOException {
477        File comicFile = testTools.getTestFile(testComicName);
478        String actualFormat = fileTools.obtainComicFormat(comicFile);
479 
480        assertEquals(testComicName, expectedFormat, actualFormat);
481    }
482 
483    private void testSortSmart(String[] source, String[] expected) {
484        assert source != null;
485        assert expected != null;
486        assert source.length == expected.length
487                : "expected.length must be " + source.length + " but is " + expected.length;
488        String[] actual = fileTools.sort(source, FileTools.SORT_SMART);
489 
490        testTools.assertEquals(expected, actual);
491    }
492 
493    private void testWriteLines(String testName, String[] testLines)
494        throws IOException {
495        String testFileName = testTools.getTestFileName(FileToolsTest.class, "testWriteLines", testName, "txt");
496        File testFileToWrite = testTools.getTestOutputFile(testFileName);
497        File expectedFile = testTools.getTestExpectedFile(testFileName);
498 
499        fileTools.writeLines(testFileToWrite, testLines);
500        testTools.assertFilesEqual(expectedFile, testFileToWrite);
501    }
502}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov