package com.twitter.common.tools;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Locale;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.TearDown;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import com.twitter.common.testing.EasyMockTest;
import static org.easymock.EasyMock.anyBoolean;
import static org.easymock.EasyMock.expect;
import static junit.framework.Assert.assertEquals;
public class AnsiColorDiagnosticListenerTest extends EasyMockTest {
private static final Pattern NEWLINE = Pattern.compile("\r?\n", Pattern.MULTILINE);
private AnsiColorDiagnosticListener<FileObject> listener;
private Diagnostic<FileObject> diagnostic;
private FileObject file;
private StringWriter out;
private StringWriter err;
@Before
public void setUp() {
out = new StringWriter();
err = new StringWriter();
listener = new AnsiColorDiagnosticListener<FileObject>(
new PrintWriter(out), new PrintWriter(err));
listener.prepareConsole(false);
addTearDown(new TearDown() {
@Override public void tearDown() {
listener.releaseConsole();
}
});
diagnostic = createMock(new Clazz<Diagnostic<FileObject>>() { });
file = createMock(FileObject.class);
}
@Test
public void testNote() throws IOException {
expectDiagnostic(Kind.NOTE, "aside", null, Diagnostic.NOPOS, Diagnostic.NOPOS,
Diagnostic.NOPOS);
control.replay();
listener.reportOn(diagnostic);
assertOut("aside");
assertNoErr();
}
@Test
public void testOther() throws IOException {
expectDiagnostic(Kind.OTHER, "unknown", null, Diagnostic.NOPOS, Diagnostic.NOPOS,
Diagnostic.NOPOS);
control.replay();
listener.reportOn(diagnostic);
assertOut("unknown");
assertNoErr();
}
@Test
public void testWarning() throws IOException {
expectDiagnostic(Kind.WARNING, "warning", "abcdefg", 1L, 3L, 2L);
control.replay();
listener.reportOn(diagnostic);
assertErr(
"warning",
"abcdefg",
" ^");
assertNoOut();
}
@Test
public void testMandatoryWarning() throws IOException {
expectDiagnostic(Kind.MANDATORY_WARNING, "mandatory warning", "abcdefg", 1L, 5L, 1L);
control.replay();
listener.reportOn(diagnostic);
assertErr(
"mandatory warning",
"abcdefg",
"^");
assertNoOut();
}
@Test
public void testError() throws IOException {
expectDiagnostic(Kind.ERROR, "error", "a\nbcd\nefg", 3L, 5L, 2L);
control.replay();
listener.reportOn(diagnostic);
assertErr(
"error",
"bcd",
" ^");
assertNoOut();
}
@Test
public void testErrorEol() throws IOException {
expectDiagnostic(Kind.ERROR, "error", "a\nbcd\n", 5L, 6L, 4L);
control.replay();
listener.reportOn(diagnostic);
assertErr(
"error",
"bcd",
" ^");
assertNoOut();
}
private void assertOut(String... lines) {
assertOutput(out, Arrays.asList(lines));
}
private void assertErr(String... lines) {
assertOutput(err, Arrays.asList(lines));
}
private void assertOutput(StringWriter writer, Iterable<String> lines) {
assertEquals(ImmutableList.builder().addAll(lines).add("").build(),
ImmutableList.copyOf(Splitter.on(NEWLINE).split(writer.toString())));
}
private void assertNoOut() {
assertNoOutput(out);
}
private void assertNoErr() {
assertNoOutput(err);
}
private void assertNoOutput(StringWriter writer) {
assertEquals("", writer.toString());
}
private void expectDiagnostic(Kind kind, String message, @Nullable String source, long start,
long end, long col) throws IOException {
expect(diagnostic.getKind()).andReturn(kind);
expect(diagnostic.getMessage(EasyMock.<Locale>notNull())).andReturn(message);
expect(diagnostic.getSource()).andReturn(file).anyTimes();
expect(diagnostic.getStartPosition()).andReturn(start).anyTimes();
expect(diagnostic.getEndPosition()).andReturn(end).anyTimes();
expect(diagnostic.getColumnNumber()).andReturn(col).anyTimes();
expect(file.getCharContent(anyBoolean())).andReturn(source).anyTimes();
}
}