1 package junit.framework;
2
3 public class ComparisonCompactor {
4
5 private static final String ELLIPSIS = "...";
6 private static final String DELTA_END = "]";
7 private static final String DELTA_START = "[";
8
9 private int fContextLength;
10 private String fExpected;
11 private String fActual;
12 private int fPrefix;
13 private int fSuffix;
14
15 public ComparisonCompactor(int contextLength, String expected, String actual) {
16 fContextLength = contextLength;
17 fExpected = expected;
18 fActual = actual;
19 }
20
21 public String compact(String message) {
22 if (fExpected == null || fActual == null || areStringsEqual()) {
23 return Assert.format(message, fExpected, fActual);
24 }
25
26 findCommonPrefix();
27 findCommonSuffix();
28 String expected = compactString(fExpected);
29 String actual = compactString(fActual);
30 return Assert.format(message, expected, actual);
31 }
32
33 private String compactString(String source) {
34 String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END;
35 if (fPrefix > 0) {
36 result = computeCommonPrefix() + result;
37 }
38 if (fSuffix > 0) {
39 result = result + computeCommonSuffix();
40 }
41 return result;
42 }
43
44 private void findCommonPrefix() {
45 fPrefix = 0;
46 int end = Math.min(fExpected.length(), fActual.length());
47 for (; fPrefix < end; fPrefix++) {
48 if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) {
49 break;
50 }
51 }
52 }
53
54 private void findCommonSuffix() {
55 int expectedSuffix = fExpected.length() - 1;
56 int actualSuffix = fActual.length() - 1;
57 for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) {
58 if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) {
59 break;
60 }
61 }
62 fSuffix = fExpected.length() - expectedSuffix;
63 }
64
65 private String computeCommonPrefix() {
66 return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix);
67 }
68
69 private String computeCommonSuffix() {
70 int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length());
71 return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : "");
72 }
73
74 private boolean areStringsEqual() {
75 return fExpected.equals(fActual);
76 }
77 }