001 /*
002 * $Id: IOTester.java,v 1.7 2014/05/04 18:34:33 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 30.03.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.junit.Assert;
028 import org.slf4j.*;
029
030 import patterntesting.annotation.check.runtime.MayReturnNull;
031 import patterntesting.runtime.io.LineReader;
032
033 /**
034 * With the IOTester you can assert if two files have equals content or
035 * if two directories have the same structure with equal files.
036 * <br/>
037 * Note: This test is not yet tested with binary files.
038 *
039 * @author oliver
040 * @since 1.1 (30.03.2011)
041 */
042 public final class IOTester {
043
044 private static final Logger log = LoggerFactory.getLogger(IOTester.class);
045
046 /** Utility class - no need to instantiate it. */
047 private IOTester() {}
048
049 /**
050 * Asserts that the content of two InputStream are equal.
051 * If they are not equals the first different line or byte will be shown.
052 *
053 * @param in1 the first InputStream
054 * @param in2 the second InputStream
055 * @throws AssertionError if the check fails
056 */
057 public static void assertContentEquals(final InputStream in1, final InputStream in2)
058 throws AssertionError {
059 assertContentEquals(new InputStreamReader(in1), new InputStreamReader(in2));
060 }
061
062 /**
063 * Asserts that the content of two InputStream are equal.
064 * If they are not equals the first different line or byte will be shown.
065 *
066 * @param in1 the first InputStream
067 * @param in2 the second InputStream
068 * @param encoding the encoding
069 * @throws AssertionError if the check fails
070 */
071 public static void assertContentEquals(final InputStream in1, final InputStream in2,
072 final Charset encoding) throws AssertionError {
073 assertContentEquals(in1, in2, Charset.defaultCharset());
074 }
075
076 /**
077 * Asserts that the content of two InputStream are equal.
078 * If they are not equals the first different line or byte will be shown.
079 *
080 * @param in1 the first InputStream
081 * @param in2 the second InputStream
082 * @param from the line number from which the comparison is started
083 * (starting with 1)
084 * @param to the last line number where the comparison ends.
085 * @throws AssertionError if the check fails
086 */
087 public static void assertContentEquals(final InputStream in1, final InputStream in2,
088 final int from, final int to) throws AssertionError {
089 assertContentEquals(in1, in2, Charset.defaultCharset(), from, to);
090 }
091
092 /**
093 * Asserts that the content of two InputStream are equal.
094 * If they are not equals the first different line or byte will be shown.
095 *
096 * @param in1 the first InputStream
097 * @param in2 the second InputStream
098 * @param encoding the encoding
099 * @param from the line number from which the comparison is started
100 * (starting with 1)
101 * @param to the last line number where the comparison ends.
102 * @throws AssertionError if the check fails
103 */
104 public static void assertContentEquals(final InputStream in1, final InputStream in2,
105 final Charset encoding, final int from, final int to) throws AssertionError {
106 assertContentEquals(new InputStreamReader(in1, encoding), new InputStreamReader(in2,
107 encoding), from, to);
108 }
109
110 /**
111 * Asserts that the content of two Readers are equal.
112 * If they are not equals the first different line or byte will be shown.
113 *
114 * @param in1 the first InputStream
115 * @param in2 the second InputStream
116 * @param ignores the lines matching this pattern will be ignored
117 * @throws AssertionError if the check fails
118 */
119 public static void assertContentEquals(final InputStream in1, final InputStream in2,
120 final Pattern... ignores) throws AssertionError {
121 assertContentEquals(in1, in2, Charset.defaultCharset(), ignores);
122 }
123
124 /**
125 * Asserts that the content of two Readers are equal.
126 * If they are not equals the first different line or byte will be shown.
127 *
128 * @param in1 the first InputStream
129 * @param in2 the second InputStream
130 * @param encoding the encoding
131 * @param ignores the lines matching this pattern will be ignored
132 * @throws AssertionError if the check fails
133 */
134 public static void assertContentEquals(final InputStream in1, final InputStream in2,
135 final Charset encoding, final Pattern... ignores) throws AssertionError {
136 assertContentEquals(new InputStreamReader(in1, encoding), new InputStreamReader(in2,
137 encoding), ignores);
138 }
139
140 /**
141 * Asserts that the content of two Readers are equal.
142 * If they are not equals the first different line or byte will be shown.
143 *
144 * @param r1 the first Reader
145 * @param r2 the second Reader
146 * @throws AssertionError if the check fails
147 */
148 // TODO: shold work also for binary files
149 public static void assertContentEquals(final Reader r1, final Reader r2) throws AssertionError {
150 assertContentEquals(new BufferedReader(r1), new BufferedReader(r2));
151 }
152
153 /**
154 * Asserts that the content of two Readers are equal.
155 * If they are not equals the first different line or byte will be shown.
156 *
157 * @param r1 the first Reader
158 * @param r2 the second Reader
159 * @param from the line number from which the comparison is started
160 * (starting with 1)
161 * @param to the last line number where the comparison ends.
162 * @throws AssertionError if the check fails
163 */
164 public static void assertContentEquals(final Reader r1, final Reader r2, final int from,
165 final int to) throws AssertionError {
166 assertContentEquals(new LineReader(r1), new LineReader(r2), from, to);
167 }
168
169 /**
170 * Asserts that the content of two Readers are equal.
171 * If they are not equals the first different line or byte will be shown.
172 *
173 * @param r1 the first Reader
174 * @param r2 the second Reader
175 * @param ignores the lines matching this pattern will be ignored
176 * @throws AssertionError if the check fails
177 */
178 public static void assertContentEquals(final Reader r1, final Reader r2,
179 final Pattern... ignores) throws AssertionError {
180 assertContentEquals(new LineReader(r1), new LineReader(r2), ignores);
181 }
182
183 /**
184 * Asserts that the content of two Readers are equal.
185 * If they are not equals the first different line or byte will be shown.
186 *
187 * @param r1 the first Reader
188 * @param r2 the second Reader
189 * @throws AssertionError if the check fails
190 */
191 public static void assertContentEquals(final BufferedReader r1, final BufferedReader r2)
192 throws AssertionError {
193 assertContentEquals(r1, r2, 1, Integer.MAX_VALUE);
194 }
195
196 /**
197 * Asserts that the content of two Readers are equal.
198 * If they are not equals the first different line or byte will be shown.
199 *
200 * @param r1 the first Reader
201 * @param r2 the second Reader
202 * @param from the line number from which the comparison is started
203 * (starting with 1)
204 * @param to the last line number where the comparison ends.
205 * @throws AssertionError if the check fails
206 */
207 public static void assertContentEquals(final LineReader r1, final LineReader r2,
208 final int from, final int to) throws AssertionError {
209 try {
210 r1.skipLines(from - 1);
211 r2.skipLines(from - 1);
212 for (int lineNo = from; lineNo <= to; lineNo++) {
213 String line1 = r1.readLine();
214 String line2 = r2.readLine();
215 if ((line1 == null) && (line2 == null)) {
216 return;
217 }
218 Assert.assertEquals("line " + lineNo + " -", line1, line2);
219 }
220 } catch (IOException ioe) {
221 throw new AssertionError(ioe);
222 }
223 }
224
225 /**
226 * Asserts that the content of two Readers are equal.
227 * If they are not equals the first different line or byte will be shown.
228 *
229 * @param r1 the first Reader
230 * @param r2 the second Reader
231 * @param ignores the lines matching this pattern will be ignored
232 * @throws AssertionError if the check fails
233 */
234 public static void assertContentEquals(final LineReader r1, final LineReader r2,
235 final Pattern... ignores) throws AssertionError {
236 try {
237 for (;;) {
238 String line1 = nextLine(r1, ignores);
239 String line2 = nextLine(r2, ignores);
240 if ((line1 == null) && (line2 == null)) {
241 return;
242 }
243 if (r1.getLineNumber() == r2.getLineNumber()) {
244 Assert.assertEquals("line " + r1.getLineNumber() + " -", line1, line2);
245 } else {
246 Assert.assertEquals("line " + r1.getLineNumber() + "/" + r2.getLineNumber() + " -", line1, line2);
247 }
248 }
249 } catch (IOException ioe) {
250 throw new AssertionError(ioe);
251 }
252 }
253
254 @MayReturnNull
255 private static String nextLine(final BufferedReader reader, final Pattern... ignores) throws IOException {
256 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
257 if (matches(line, ignores)) {
258 log.trace("\"{}\" maches {} and is ignored.", line, ignores);
259 } else {
260 return line;
261 }
262 }
263 return null;
264 }
265
266 private static boolean matches(final String line, final Pattern[] ignores) {
267 for (int i = 0; i < ignores.length; i++) {
268 if (ignores[i].matcher(line).matches()) {
269 return true;
270 }
271 }
272 return false;
273 }
274
275 }
276