package com.github.signed.changelog;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
public class IsPrefix extends TypeSafeDiagnosingMatcher<String> {
public static Matcher<String> isAPrefixIn(String goldMaster) {
return new IsPrefix(goldMaster);
}
private final String longer;
public IsPrefix(String longer) {
this.longer = longer;
}
public String greatestCommonPrefix(String a, String b) {
int minLength = Math.min(a.length(), b.length());
for (int i = 0; i < minLength; i++) {
if (a.charAt(i) != b.charAt(i)) {
return a.substring(0, i);
}
}
return a.substring(0, minLength);
}
@Override
protected boolean matchesSafely(String item, Description description) {
boolean isPrefix = longer.startsWith(item);
if (!isPrefix) {
String sharedPrefix = greatestCommonPrefix(item, longer);
int blub = sharedPrefix.lastIndexOf('\n') + 1;
String startOfMismatchLine = sharedPrefix.substring(blub);
int start = sharedPrefix.length();
int numberOfCharactersAfter = 30;
String before = sharedPrefix.substring(blub - 30, blub);
description.appendText(replaceNewLine(before));
description.appendText("\n");
description.appendText(replaceNewLine(startOfMismatchLine + "|> " + nextIfThere(start, numberOfCharactersAfter, longer)));
description.appendText("\n");
description.appendText(replaceNewLine(startOfMismatchLine + "|> " + nextIfThere(start, numberOfCharactersAfter, item)));
}
return isPrefix;
}
private String replaceNewLine(String string) {
return string.replaceAll("\n", "\\\\n");
}
private String nextIfThere(int start, int numberOfCharactersAfter, String string) {
int endIndex = Math.min(string.length(), start + numberOfCharactersAfter);
return string.substring(start, endIndex);
}
@Override
public void describeTo(Description description) {
description.appendText("being a prefix");
}
}