01: package com.canoo.webtest.extension;
02:
03: import java.io.IOException;
04:
05: import org.apache.commons.codec.binary.Hex;
06: import org.apache.commons.io.IOUtils;
07: import org.apache.commons.lang.ArrayUtils;
08:
09: import com.canoo.webtest.engine.StepExecutionException;
10: import com.gargoylesoftware.htmlunit.WebResponse;
11:
12: /**
13: * Performs a binary comparison of the content.
14: * @author Marc Guillemot
15: */
16: public class VerifyContentBinDiff implements VerifyContentDiff {
17: /**
18: * {@inheritDoc}
19: */
20: public String compare(final WebResponse reference,
21: final WebResponse actual, final String referenceLabel,
22: final String actualLabel) {
23:
24: if (sameContent(reference, actual)) {
25: return null;
26: } else {
27: return produceBinDiffMessage(actual.getResponseBody(),
28: reference.getResponseBody());
29: }
30: }
31:
32: private boolean sameContent(final WebResponse reference,
33: final WebResponse actual) {
34: try {
35: return IOUtils.contentEquals(
36: reference.getContentAsStream(), actual
37: .getContentAsStream());
38: } catch (final IOException e) {
39: throw new StepExecutionException("Error reading content", e);
40: }
41: }
42:
43: protected String produceBinDiffMessage(final byte[] actualBytes,
44: final byte[] referenceBytes) {
45: final int extractLength = 10;
46: final int minLength = Math.min(actualBytes.length,
47: referenceBytes.length);
48: for (int i = 0; i < minLength; i++) {
49: if (actualBytes[i] != referenceBytes[i]) {
50: // extract 10 bytes (if available) to show difference in context
51: final byte[] extract1 = ArrayUtils.subarray(
52: actualBytes, i, i + extractLength);
53: final byte[] extract2 = ArrayUtils.subarray(
54: referenceBytes, i, i + extractLength);
55: return "First difference at position " + (i + 1) + ": "
56: + String.valueOf(Hex.encodeHex(extract1))
57: + " <> "
58: + String.valueOf(Hex.encodeHex(extract2));
59: }
60: }
61:
62: // one file is contained in the other
63: final byte[] longerArray;
64: final String msg;
65: if (actualBytes.length < referenceBytes.length) {
66: longerArray = referenceBytes;
67: msg = "Reference binary content starts with actual binary content";
68: } else {
69: longerArray = actualBytes;
70: msg = "Actual binary content starts with reference binary content";
71: }
72: final byte[] startOfLonger = ArrayUtils.subarray(longerArray,
73: minLength, minLength + extractLength);
74: return msg + ". Longer content continues with: "
75: + String.valueOf(Hex.encodeHex(startOfLonger));
76: }
77: }
|