001    /*
002     * $Id: FileTester.java,v 1.7 2013/11/13 20:09:28 oboehm Exp $
003     *
004     * Copyright (c) 2011 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 06.04.2011 by oliver (ob@oasd.de)
019     */
020    
021    package patterntesting.runtime.junit;
022    
023    import java.io.*;
024    import java.nio.charset.Charset;
025    import java.util.regex.Pattern;
026    
027    import org.apache.commons.io.FileUtils;
028    import org.junit.Assert;
029    
030    import patterntesting.runtime.io.FileHelper;
031    
032    /**
033     * The Class FileTester.
034     *
035     * @author oliver
036     * @since 1.1 (06.04.2011)
037     */
038    public class FileTester {
039    
040        /** Utility class - no need to instantiate it. */
041        private FileTester() {}
042    
043        /**
044         * Asserts that the content of two files are equal.
045         * If they are not equals the first different line or byte will be shown.
046         *
047         * @param file1 the first file
048         * @param file2 the second file
049         * @throws AssertionError if the check fails
050         */
051        public static void assertContentEquals(final File file1, final File file2)
052                throws AssertionError {
053            assertContentEquals(file1, file2, Charset.defaultCharset());
054        }
055    
056        /**
057         * Asserts that the content of two files are equal.
058         * If they are not equals the first different line or byte will be shown.
059         *
060         * @param file1 the first file
061         * @param file2 the second file
062         * @param from the line number from which the comparison is started
063         *            (starting with 1)
064         * @param to the last line number where the comparison ends.
065         * @throws AssertionError if the check fails
066         */
067        public static void assertContentEquals(final File file1, final File file2, final int from, final int to)
068                throws AssertionError {
069            assertContentEquals(file1, file2, from, to, Charset.defaultCharset());
070        }
071    
072        /**
073         * Asserts that the content of two files are equal.
074         * If they are not equals the first different line or byte will be shown.
075         * <p>
076         * The encoding is only important for the output if the two files are not
077         * equals.
078         * </p>
079         *
080         * @param file1 the first file
081         * @param file2 the second file
082         * @param encoding the encoding
083         * @throws AssertionError if the check fails
084         */
085        public static void assertContentEquals(final File file1, final File file2, final String encoding)
086                throws AssertionError {
087            assertContentEquals(file1, file2, Charset.forName(encoding));
088        }
089    
090        /**
091         * Asserts that the content of two files are equal.
092         * If they are not equals the first different line or byte will be shown.
093         * <p>
094         * The encoding is only important for the output if the two files are not
095         * equals.
096         * </p>
097         *
098         * @param file1 the first file
099         * @param file2 the second file
100         * @param from the line number from which the comparison is started
101         *            (starting with 1)
102         * @param to the last line number where the comparison ends.
103         * @param encoding the encoding
104         * @throws AssertionError if the check fails
105         */
106        public static void assertContentEquals(final File file1, final File file2, final int from,
107                final int to, final String encoding) throws AssertionError {
108            assertContentEquals(file1, file2, from, to, Charset.forName(encoding));
109        }
110    
111        /**
112         * Asserts that the content of two files are equal.
113         * If they are not equals the first different line or byte will be shown.
114         * <p>
115         * The encoding is only important for the output if the two files are not
116         * equals.
117         * </p>
118         *
119         * @param file1 the first file
120         * @param file2 the second file
121         * @param encoding the encoding
122         * @throws AssertionError if the check fails
123         */
124        public static void assertContentEquals(final File file1, final File file2, final Charset encoding)
125                throws AssertionError {
126            try {
127                if (FileUtils.contentEquals(file1, file2)) {
128                    return;
129                }
130                assertContentEquals(file1, file2, 1, Integer.MAX_VALUE, encoding);
131            } catch (IOException ioe) {
132                throwAssertionError("can't compare " + file1 + " with " + file2, ioe);
133            }
134        }
135    
136        /**
137         * Asserts that the content of two files are equal. If they are not equals
138         * the first different line or byte will be shown.
139         * <p>
140         * The encoding is only important for the output if the two files are not
141         * equals.
142         * </p>
143         *
144         * @param file1 the first file
145         * @param file2 the second file
146         * @param from the line number from which the comparison is started
147         *            (starting with 1)
148         * @param to the last line number where the comparison ends.
149         * @param encoding the encoding
150         * @throws AssertionError if the check fails
151         */
152        public static void assertContentEquals(final File file1, final File file2, final int from,
153                final int to, final Charset encoding) throws AssertionError {
154            try {
155                Reader r1 = new InputStreamReader(new FileInputStream(file1), encoding);
156                Reader r2 = new InputStreamReader(new FileInputStream(file2), encoding);
157                try {
158                    IOTester.assertContentEquals(r1, r2, from, to);
159                } finally {
160                    r1.close();
161                    r2.close();
162                }
163            } catch (IOException ioe) {
164                throwAssertionError("can't compare " + file1 + " with " + file2, ioe);
165            }
166        }
167    
168        /**
169         * Asserts that the content of two files are equal. Lines which matches the
170         * given 'ignores' pattern will be ignored for comparison. E.g. if you want
171         * to ignore two property files and want to ignore the comments and empty
172         * lines you could use
173         *
174         * <pre>
175         *     Pattern.compile("#.*"), Pattern.compile("[ \\t]*"
176         * </pre>
177         *
178         * as ignores parameters.
179         * <p>
180         * If the two files are not equals the first different line or byte will be
181         * shown.
182         * </p>
183         *
184         * @param file1 the first file
185         * @param file2 the second file
186         * @param ignores the line pattern which should be ignored
187         * @throws AssertionError if the check fails
188         * @see #assertContentEquals(File, File, Charset, Pattern...)
189         * @since 1.4
190         */
191        public static void assertContentEquals(final File file1, final File file2,
192                final Pattern... ignores) throws AssertionError {
193            assertContentEquals(file1, file2, Charset.defaultCharset(), ignores);
194        }
195    
196        /**
197         * Asserts that the content of two files are equal. Lines which matches the
198         * given 'ignores' pattern will be ignored for comparison. E.g. if you want
199         * to ignore two property files and want to ignore the comments and empty
200         * lines you could use
201         *
202         * <pre>
203         *     Pattern.compile("#.*"), Pattern.compile("[ \\t]*"
204         * </pre>
205         *
206         * as ignores parameters.
207         * <p>
208         * If the two files are not equals the first different line or byte will be
209         * shown.
210         * </p>
211         *
212         * @param file1 the first file
213         * @param file2 the second file
214         * @param encoding the file encoding
215         * @param ignores the line pattern which should be ignored
216         * @throws AssertionError if the check fails
217         * @since 1.4
218         */
219        public static void assertContentEquals(final File file1, final File file2,
220                final Charset encoding, final Pattern... ignores) throws AssertionError {
221            try {
222                Reader r1 = new InputStreamReader(new FileInputStream(file1), encoding);
223                Reader r2 = new InputStreamReader(new FileInputStream(file2), encoding);
224                try {
225                    IOTester.assertContentEquals(r1, r2, ignores);
226                } finally {
227                    r1.close();
228                    r2.close();
229                }
230            } catch (IOException ioe) {
231                throwAssertionError("can't compare " + file1 + " with " + file2, ioe);
232            }
233    
234        }
235    
236        /**
237         * Two files are considered equals if the would point to the same file
238         * location on the disk.
239         *
240         * @param file1 e.g. file "/a/b/c"
241         * @param file2 e.g. file "/a/b/../b/c"
242         */
243        public static void assertEquals(final File file1, final File file2) {
244            Assert.assertEquals(FileHelper.normalize(file1), FileHelper.normalize(file2));
245        }
246    
247        private static void throwAssertionError(final String msg, final Throwable t) throws AssertionError {
248            AssertionError error = new AssertionError(msg);
249            error.initCause(t);
250            throw error;
251        }
252    
253    }
254