001/*
002 * #%L
003 * Netarchivesuite - common - test
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.testutils;
025
026import java.io.BufferedReader;
027import java.io.File;
028import java.io.FileReader;
029import java.io.IOException;
030import java.util.regex.Pattern;
031
032import org.hamcrest.CoreMatchers;
033import org.hamcrest.core.IsNot;
034import org.junit.Assert;
035
036import dk.netarkivet.common.utils.FileUtils;
037import junit.framework.TestCase;
038
039/**
040 * Utility functions for asserting statements about files. Notice that using these may cause the files to be re-read
041 * several times. This ought to be cheap, but may not be for big files.
042 */
043
044public class FileAsserts {
045    /**
046     * Assert that a given string exists in the file. If it doesn't, fail and print the file contents. If the file
047     * couldn't be read, fail and print the error message.
048     *
049     * @param msg An explanatory message.
050     * @param str A string to find in the file.
051     * @param file A file to scan.
052     */
053    public static void assertFileContains(String msg, String str, File file) {
054        try {
055            String contents = FileUtils.readFile(file);
056            // http://stackoverflow.com/a/1092241/53897
057            Assert.assertThat(contents, CoreMatchers.containsString(str));
058        } catch (IOException e) {
059            TestCase.fail("Should be able to read " + file + ", but got " + e);
060        }
061    }
062
063    /**
064     * Assert that a given pattern has a match in the file. If it doesn't, fail and print the file contents. If the file
065     * couldn't be read, fail and print the error message.
066     *
067     * @param msg An explanatory message.
068     * @param regexp A pattern to search for in the file.
069     * @param file A file to scan.
070     */
071    public static void assertFileMatches(String msg, String regexp, File file) {
072        try {
073            String contents = FileUtils.readFile(file);
074            Pattern pattern = Pattern.compile(regexp, Pattern.MULTILINE);
075            // https://github.com/derari/cthul/wiki/Matchers#string-matchers
076            Assert.assertThat(contents, org.cthul.matchers.CthulMatchers.containsPattern(pattern));
077        } catch (IOException e) {
078            TestCase.fail("Should be able to read " + file + ", but got " + e);
079        }
080    }
081
082    /**
083     * Assert that a given string exists in the file. If it doesn't, fail and print the file contents. If the file
084     * couldn't be read, fail and print the error message.
085     *
086     * @param msg An explanatory message.
087     * @param file A file to scan.
088     * @param str A string to find in the file.
089     */
090    public static void assertFileNotContains(String msg, File file, String str) {
091        try {
092            String contents = FileUtils.readFile(file);
093            // http://stackoverflow.com/a/1092241/53897
094            Assert.assertThat(contents, IsNot.not(CoreMatchers.containsString(str)));
095        } catch (IOException e) {
096            TestCase.fail("Should be able to read " + file + ", but got " + e);
097        }
098    }
099
100    /**
101     * Assert that a given file has the expected number of lines If it doesn't, fail and print the file contents. If the
102     * file couldn't be read, fail and print the error message.
103     *
104     * @param msg an explanatory message
105     * @param file the File to check
106     * @param n the expected number of lines
107     */
108    public static void assertFileNumberOfLines(String msg, File file, int n) {
109        try {
110            BufferedReader r = new BufferedReader(new FileReader(file));
111            int i = 0;
112            String line = "";
113            while (line != null) {
114                line = r.readLine();
115                if (line != null) {
116                    i++;
117                }
118            }
119            if (i != n) {
120                TestCase.fail(msg + ": Expected " + n + " lines in " + file + " but found only " + i);
121            }
122            r.close();
123        } catch (IOException e) {
124            TestCase.fail(msg + ": Couldn't read " + file + ", got " + e);
125        }
126
127    }
128
129    /**
130     * Assert that a given file contains exactly the string given. This will read the given file's contents into a
131     * string.
132     *
133     * @param msg An explanatory message
134     * @param toMatch The string that should be the full contents of the file
135     * @param file The file that the string should be in.
136     */
137    public static void assertFileContainsExactly(String msg, String toMatch, File file) {
138        try {
139            String contents = FileUtils.readFile(file);
140            TestCase.assertEquals(msg, toMatch, contents);
141        } catch (IOException e) {
142            TestCase.fail("Should be able to read " + file + ", but got " + e);
143        }
144    }
145}