001package junit.framework;
002
003public class ComparisonCompactor {
004
005    private static final String ELLIPSIS = "...";
006    private static final String DELTA_END = "]";
007    private static final String DELTA_START = "[";
008
009    private int fContextLength;
010    private String fExpected;
011    private String fActual;
012    private int fPrefix;
013    private int fSuffix;
014
015    public ComparisonCompactor(int contextLength, String expected, String actual) {
016        fContextLength = contextLength;
017        fExpected = expected;
018        fActual = actual;
019    }
020
021    @SuppressWarnings("deprecation")
022    public String compact(String message) {
023        if (fExpected == null || fActual == null || areStringsEqual()) {
024            return Assert.format(message, fExpected, fActual);
025        }
026
027        findCommonPrefix();
028        findCommonSuffix();
029        String expected = compactString(fExpected);
030        String actual = compactString(fActual);
031        return Assert.format(message, expected, actual);
032    }
033
034    private String compactString(String source) {
035        String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END;
036        if (fPrefix > 0) {
037            result = computeCommonPrefix() + result;
038        }
039        if (fSuffix > 0) {
040            result = result + computeCommonSuffix();
041        }
042        return result;
043    }
044
045    private void findCommonPrefix() {
046        fPrefix = 0;
047        int end = Math.min(fExpected.length(), fActual.length());
048        for (; fPrefix < end; fPrefix++) {
049            if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) {
050                break;
051            }
052        }
053    }
054
055    private void findCommonSuffix() {
056        int expectedSuffix = fExpected.length() - 1;
057        int actualSuffix = fActual.length() - 1;
058        for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) {
059            if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) {
060                break;
061            }
062        }
063        fSuffix = fExpected.length() - expectedSuffix;
064    }
065
066    private String computeCommonPrefix() {
067        return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix);
068    }
069
070    private String computeCommonSuffix() {
071        int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length());
072        return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : "");
073    }
074
075    private boolean areStringsEqual() {
076        return fExpected.equals(fActual);
077    }
078}