package org.jtheque.utils.unit.file;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.BufferedInputStream;
import java.util.Collection;
import java.util.ArrayList;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import static org.junit.Assert.*;
/*
* This file is part of JTheque.
*
* JTheque is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JTheque is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JTheque. If not, see .
*/
/**
* A Unit utility class to test file operations. This class is made to facilitate the tests of file operations on JUnit tests.
* This class emulate a simple file system in a temporary folder.
*
* @author Baptiste Wicht
*/
public final class FileUnit {
private static final File ROOT_FOLDER = new File(System.getProperty("java.io.tmpdir"), "unit");
/**
* Utility class, not instanciable.
*/
private FileUnit() {
super();
}
//Utility methods
/**
* Init the test's file system.
*/
public static void initTestFileSystem() {
createFolderIfNecessary(ROOT_FOLDER);
}
/**
* Clear the test's file system. All the created files will be deleted.
*/
public static void clearTestFileSystem() {
deleteIfNecessary(ROOT_FOLDER);
}
/**
* Return the path to the root folder of the test's file system.
*
* @return The path to the root folder of the test's file system.
*/
public static String getRootFolder() {
return ROOT_FOLDER.getAbsolutePath();
}
/**
* Return the File
object of a path on the test's file system.
*
* @param path The path on the test's file system.
*
* @return Return the corresponding File
object.
*/
public static File getFile(String path){
return new File(ROOT_FOLDER, path);
}
/**
* Return the File
object of the path in the specified folder on the test's file system.
*
* @param folder The path to the parent folder.
* @param path The path of the file.
*
* @return The corresponding File
object,
*/
public static File getFile(String folder, String path) {
return new File(getFile(folder), path);
}
/**
* Return the real path of the path on the test's file system.
*
* @param path The path on the test's file system.
*
* @return The corresponding path on the real file system.
*/
public static String getPath(String path){
return getFile(path).getAbsolutePath();
}
/**
* Return the real path of the path on the specified folder on the test's file system.
*
* @param folder The path to the parent folder.
* @param path The path of the file.
*
* @return The corresponding path on the real file system.
*/
public static String getPath(String folder, String path) {
return getFile(folder, path).getAbsolutePath();
}
/**
* Return an InputStream
to the path.
*
* @param path The path on the test's file system.
*
* @return The InputStream
to the path. This stream is still buffered.
*
* @see InputStream
*/
public static InputStream getInputStream(String path){
try {
return new BufferedInputStream(new FileInputStream(getPath(path)));
} catch (FileNotFoundException e) {
fail("Unable to open stream to {" + path + " } due to " + e.getMessage());
}
return null;
}
/**
* Add a file to the test's file system.
*
* @param path The path to the file on the test's file system.
*/
public static void addFile(String path) {
createFileIfNecessary(getFile(path));
}
/**
* Add a file to the test's file system in the specified folder.
*
* @param folder The path to the folder on the test's file system.
* @param path The path to the file on the test's file system.
*/
public static void addFile(String folder, String path) {
createFileIfNecessary(getFile(folder, path));
}
/**
* Add a folder to the test's file system.
*
* @param path The path to the folder on the test's file system.
*/
public static void addFolder(String path) {
createFolderIfNecessary(getFile(path));
}
/**
* Add a file to the test's file system in the specified folder.
*
* @param folder The path to the folder on the test's file system.
* @param path The path to the file on the test's file system.
*/
public static void addFolder(String folder, String path) {
createFolderIfNecessary(getFile(folder, path));
}
/**
* Set the content of the file specified by the path.
*
* @param path The path to the file on the test's file system.
* @param content The content of the file.
*/
public static void setContent(String path, String content){
assertIsFile(path);
write(content, getFile(path));
}
/**
* Set the content of the file specified by the path.
*
* @param folder The path to the folder on the test's file system.
* @param path The path to the file on the test's file system.
* @param content The content of the file.
*/
public static void setContent(String folder, String path, String content){
assertIsFile(folder, path);
write(content, getFile(folder, path));
}
//Assert methods
/**
* Assert that the test's file system has been correctly created.
*/
public static void assertInitOK(){
assertTrue(ROOT_FOLDER.exists());
}
/**
* Assert that the file referenced by the specified path exists.
*
* @param path The path to the file to test.
*/
public static void assertFileExists(String path){
assertTrue("The file {" + path + "} must exists", getFile(path).exists());
}
/**
* Assert that the file referenced by the specified path in the specified folder exists.
*
* @param folder The path to the folder on the test's file system.
* @param path The path to the file to test.
*/
public static void assertFileExists(String folder, String path) {
assertTrue("The file {" + folder + '/' + path + "} must not exists", getFile(folder, path).exists());
}
/**
* Assert that the file referenced by the specified path doesn't exists.
*
* @param path The path to the file to test.
*/
public static void assertFileNotExists(String path) {
assertFalse("The file {" + path + "} must not exists", getFile(path).exists());
}
/**
* Assert that the folder contains the specified file.
*
* @param folder The path the folder in the test's file system to test.
* @param file The file that we must found in the specified folder.
*/
public static void assertDirectoryContains(String folder, String file) {
assertIsDirectory(folder);
boolean found = false;
for(File f : getFile(folder).listFiles()){
if(f.getName().equals(file)){
found = true;
break;
}
}
assertTrue("The directory must contains the file " + file, found);
}
/**
* Assert that the folder contains the specified number of files.
*
* @param folder The path to the folder on the test's file system.
* @param files The expected number of files.
*/
public static void assertDirectoryNumberOfFiles(String folder, int files) {
assertIsDirectory(folder);
int size = getFile(folder).listFiles().length;
assertEquals("The directory must contains " + files + " files but contains " + size + " files", files, size);
}
/**
* Assert that the file referenced by the specified path is a directory.
*
* @param file The path to the file on the test's file system.
*/
public static void assertIsDirectory(String file) {
assertTrue(file + " must be a directory", getFile(file).isDirectory());
}
/**
* Assert that the file referenced by the specified path is a file.
*
* @param file The path to the file on the test's file system.
*/
public static void assertIsFile(String file) {
assertTrue(file + " must be a file", getFile(file).isFile());
}
/**
* Assert that the file referenced by the specified path is a file.
*
* @param folder The path to the parent folder on the test's file system.
* @param file The path to the file on the test's file system.
*/
public static void assertIsFile(String folder, String file) {
assertTrue(folder + '/' + file + " must be a file", getFile(folder, file).isFile());
}
/**
* Assert that the content of the file referenced by the specified path equals the specified content.
*
* @param path The path to the file in test's file system.
* @param expectedContent The expected content.
*/
public static void assertFileContentEquals(String path, String expectedContent){
assertIsFile(path);
String content = getContent(getFile(path));
assertEquals("The content of the must be " + expectedContent + " but it's content is " + content, expectedContent, content);
}
/**
* Assert that the size of the file is the expected size.
*
* @param path The path to the file on the test's file system.
* @param size The expected size.
*/
public static void assertFileSizeEquals(String path, long size) {
assertIsFile(path);
long actualSize = getFile(path).length();
assertEquals("The size of the file must be " + size + " but is actually " + actualSize, size, actualSize);
}
/**
* Assert that the size of the file referenced by the specified path is lower than the specified size.
*
* @param path The path to the file on the test's file system.
* @param size The size.
*/
public static void assertFileSizeLowerThan(String path, long size) {
assertIsFile(path);
long actualSize = getFile(path).length();
if(actualSize >= size){
fail(path + " must be lower than " + size + " but was actually " + actualSize);
}
}
/**
* Assert that the size of the file referenced by the specified path is greater than the specified size.
*
* @param path The path to the file on the test's file system.
* @param size The size.
*/
public static void assertFileSizeGreaterThan(String path, long size) {
assertIsFile(path);
long actualSize = getFile(path).length();
if(actualSize <= size){
fail(path + " must be greater than " + size + " but was actually " + actualSize);
}
}
/**
* Assert that the zip file referenced by the specified path contains all the specified files.
*
* @param path The path to the zip file in the test's file system.
* @param files All the files that the zip must contains.
*/
public static void assertZipContains(String path, String... files) {
if(files.length == 0){
return;
}
Collection entries = new ArrayList(10);
ZipInputStream zis = new ZipInputStream(getInputStream(path));
try {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
entries.add(entry.getName());
}
} catch (FileNotFoundException e) {
fail("Unable to read zip due to {" + e.getMessage() + '}');
} catch (IOException e) {
fail("Unable to read zip due to {" + e.getMessage() + '}');
} finally {
try {
zis.close();
} catch (IOException e) {
fail("Unable to read zip due to {" + e.getMessage() + '}');
}
}
for(String file : files){
assertTrue("The zip must contains " + file, entries.contains(file));
}
}
//Private methods
/**
* Create the specified file if it not exists.
*
* @param file The file to create.
*/
private static void createFileIfNecessary(File file) {
if (!file.exists()) {
try {
if(!file.createNewFile()){
fail("Unable to create the file {" + file.getAbsolutePath() + " }");
}
} catch (IOException e) {
fail("Unable to create the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
}
}
}
/**
* Create the specified folder if it not exists.
*
* @param folder The folder to create.
*/
private static void createFolderIfNecessary(File folder) {
if (!folder.exists() && !folder.mkdirs()){
fail("Unable to create the folder {" + folder.getAbsolutePath() + " }");
}
}
/**
* Delete the file if it exists.
*
* @param file The file of folder to delete.
*/
private static void deleteIfNecessary(File file) {
if(file.exists()){
if (file.isDirectory()) {
for (File f : file.listFiles()) {
deleteIfNecessary(f);
}
}
if (!file.delete()) {
fail("Unable to delete the file {" + file.getAbsolutePath() + " }");
}
}
}
/**
* Return the content of the file in a String.
*
* @param file The file to get the content from.
*
* @return The content of the file.
*/
private static String getContent(File file){
StringBuilder builder = new StringBuilder(100);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line;
boolean first = true;
while((line = reader.readLine()) != null){
if(first){
first = false;
} else {
builder.append('\n');
}
builder.append(line);
}
} catch (FileNotFoundException e) {
fail("Unable to read the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
} catch (IOException e) {
fail("Unable to read the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
} finally {
if(reader != null){
try {
reader.close();
} catch (IOException e) {
fail("Unable to read the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
}
}
}
return builder.toString();
}
/**
* Write the specified content to the specified file.
*
* @param content The content to write.
* @param file The file to write the content in.
*/
private static void write(String content, File file) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(file));
writer.write(content);
} catch (IOException e) {
fail("Unable to write the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
} finally {
if(writer != null){
try {
writer.close();
} catch (IOException e) {
fail("Unable to write the file {" + file.getAbsolutePath() + " } due to " + e.getMessage());
}
}
}
}
}