package com.equalexperts.logging.impl;
import org.junit.Test;
import static org.junit.Assert.*;
public class ThrowableFingerprintCalculatorTest {
private final ThrowableFingerprintCalculator calculator = new ThrowableFingerprintCalculator();
@Test
public void calculateFingerprint_shouldGenerateTheSameFingerprint_givenTwoIdenticalThrowables() throws Exception {
//ensure the exceptions are identical by giving them the same message, same class, and same stack trace
String exceptionMessage = "message";
Throwable firstException = new RuntimeException(exceptionMessage);
Throwable secondException = new RuntimeException(exceptionMessage);
firstException.setStackTrace(constructCustomStackTrace());
secondException.setStackTrace(constructCustomStackTrace());
String firstFingerprint = calculator.calculateFingerprint(firstException);
String secondFingerprint = calculator.calculateFingerprint(secondException);
assertEquals(firstFingerprint, secondFingerprint);
}
@Test
public void calculateFingerprint_shouldReturnTheSameFingerprint_givenTheSameExceptionTwice() throws Exception {
Throwable t = new RuntimeException();
String expectedFingerprint = calculator.calculateFingerprint(t);
String actualFingerprint = calculator.calculateFingerprint(t);
assertEquals(expectedFingerprint, actualFingerprint);
}
@Test
public void calculateFingerprint_shouldReturnADifferentFingerprint_whenTheStackTraceChanges() throws Exception {
Throwable t = new RuntimeException();
String originalFingerprint = calculator.calculateFingerprint(t);
t.setStackTrace(constructCustomStackTrace());
String newFingerprint = calculator.calculateFingerprint(t);
assertNotEquals(originalFingerprint, newFingerprint);
}
@Test
public void calculateFingerprint_shouldReturnDifferentFingerprints_forDifferentThrowableTypes() throws Exception {
//same message and stack trace to create throwable instances that differ only by type
String message = "foo";
Throwable a = new Exception(message);
a.setStackTrace(constructCustomStackTrace());
Throwable b = new RuntimeException(message);
b.setStackTrace(constructCustomStackTrace());
String fingerprintA = calculator.calculateFingerprint(a);
String fingerprintB = calculator.calculateFingerprint(b);
assertNotEquals(fingerprintA, fingerprintB);
}
@Test
public void calculateFingerprint_shouldReturnDifferentFingerprints_givenDifferentMessages() throws Exception {
//same class and stack trace to create throwable instances that differ only by message
Throwable a = new RuntimeException("a");
a.setStackTrace(constructCustomStackTrace());
Throwable b = new RuntimeException("b");
b.setStackTrace(constructCustomStackTrace());
String fingerprintA = calculator.calculateFingerprint(a);
String fingerprintB = calculator.calculateFingerprint(b);
assertNotEquals(fingerprintA, fingerprintB);
}
@Test
public void calculateFingerprint_shouldReturnADifferentFingerprint_givenADifferentCause() throws Exception {
Throwable t = new RuntimeException();
String originalFingerprint = calculator.calculateFingerprint(t);
t.initCause(new RuntimeException());
String modifiedFingerprint = calculator.calculateFingerprint(t);
assertNotEquals(originalFingerprint, modifiedFingerprint);
}
@Test
public void calculateFingerprint_shouldReturnADifferentFingerprint_givenAChangeInSuppressedExceptions() throws Exception {
Throwable t = new RuntimeException();
String originalFingerprint = calculator.calculateFingerprint(t);
t.addSuppressed(new RuntimeException());
String modifiedFingerprint = calculator.calculateFingerprint(t);
assertNotEquals(originalFingerprint, modifiedFingerprint);
}
private StackTraceElement[] constructCustomStackTrace() {
return new StackTraceElement[]{
new StackTraceElement("org,example.Foo", "baz", "Foo.java", 128),
new StackTraceElement("org,example.Foo", "bar", "Foo.java", 67),
new StackTraceElement("org,example.Foo", "foo", "Foo.java", 42),
new StackTraceElement("org,example.Foo", "main", "Foo.java", 21)
};
}
}