Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.github.ascopes.jct.diagnostics;

import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;

import io.github.ascopes.jct.annotations.Nullable;
Expand Down Expand Up @@ -65,7 +66,7 @@ public TraceDiagnostic(
this.timestamp = requireNonNull(timestamp, "timestamp");
this.threadId = threadId;
this.threadName = threadName;
this.stackTrace = requireNonNull(stackTrace, "stackTrace");
this.stackTrace = unmodifiableList(requireNonNull(stackTrace, "stackTrace"));
this.original = requireNonNull(original, "original");
}

Expand Down Expand Up @@ -137,7 +138,7 @@ public long getThreadId() {
/**
* Get the thread name for the thread that created this diagnostic.
*
* @return the thread name, if known.
* @return the thread name, if known, or an empty optional otherwise.
*/
public Optional<String> getThreadName() {
return Optional.ofNullable(threadName);
Expand All @@ -146,7 +147,7 @@ public Optional<String> getThreadName() {
/**
* Get the stacktrace of where the diagnostic was written from.
*
* @return the stacktrace.
* @return the stacktrace, in an unmodifiable list.
*/
public List<StackTraceElement> getStackTrace() {
return stackTrace;
Expand All @@ -158,11 +159,11 @@ public String toString() {
.attribute("timestamp", timestamp)
.attribute("threadId", threadId)
.attribute("threadName", threadName)
.attribute("kind", getKind())
.attribute("code", getCode())
.attribute("column", getColumnNumber())
.attribute("line", getLineNumber())
.attribute("message", getMessage(Locale.ROOT))
.attribute("kind", original.getKind())
.attribute("code", original.getCode())
.attribute("column", original.getColumnNumber())
.attribute("line", original.getLineNumber())
.attribute("message", original.getMessage(Locale.ROOT))
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import static io.github.ascopes.jct.testing.helpers.Fixtures.someStackTraceList;
import static java.time.Instant.now;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.api.BDDAssertions.thenCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.verify;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.github.ascopes.jct.diagnostics.TraceDiagnostic;
import java.util.Locale;
Expand All @@ -50,8 +49,11 @@ class TraceDiagnosticTest {
@DisplayName("null original diagnostics are rejected")
@Test
void nullDiagnosticsAreRejected() {
// Given
var stack = someStackTraceList();
thenCode(() -> new TraceDiagnostic<>(now(), 123, "foo", stack, null))

// Then
assertThatThrownBy(() -> new TraceDiagnostic<>(now(), 123, "foo", stack, null))
.isInstanceOf(NullPointerException.class)
.hasMessage("original");
}
Expand All @@ -64,7 +66,7 @@ void getKindDelegates(Kind expected) {
var original = someDiagnostic();
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
given(original.getKind()).willReturn(expected);
when(original.getKind()).thenReturn(expected);

// Then
assertThat(wrapped.getKind()).isSameAs(expected);
Expand All @@ -78,8 +80,7 @@ void getSourceDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var source = mock(JavaFileObject.class);

given(original.getSource()).willReturn(source);
when(original.getSource()).thenReturn(source);

// Then
assertThat(wrapped.getSource()).isSameAs(source);
Expand All @@ -93,7 +94,7 @@ void getPositionDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var position = new Random().nextLong();
given(original.getPosition()).willReturn(position);
when(original.getPosition()).thenReturn(position);

// Then
assertThat(wrapped.getPosition()).isEqualTo(position);
Expand All @@ -107,7 +108,7 @@ void getStartPositionDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var startPosition = new Random().nextLong();
given(original.getStartPosition()).willReturn(startPosition);
when(original.getStartPosition()).thenReturn(startPosition);

// Then
assertThat(wrapped.getStartPosition()).isEqualTo(startPosition);
Expand All @@ -121,7 +122,7 @@ void getEndPositionDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var endPosition = new Random().nextLong();
given(original.getEndPosition()).willReturn(endPosition);
when(original.getEndPosition()).thenReturn(endPosition);

// Then
assertThat(wrapped.getEndPosition()).isEqualTo(endPosition);
Expand All @@ -135,7 +136,7 @@ void getLineNumberDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var lineNumber = new Random().nextLong();
given(original.getLineNumber()).willReturn(lineNumber);
when(original.getLineNumber()).thenReturn(lineNumber);

// Then
assertThat(wrapped.getLineNumber()).isEqualTo(lineNumber);
Expand All @@ -149,7 +150,7 @@ void getColumnNumberDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var columnNumber = new Random().nextLong();
given(original.getColumnNumber()).willReturn(columnNumber);
when(original.getColumnNumber()).thenReturn(columnNumber);

// Then
assertThat(wrapped.getColumnNumber()).isEqualTo(columnNumber);
Expand All @@ -164,7 +165,7 @@ void getCodeDelegates(String expected) {
var original = someDiagnostic();
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
given(original.getCode()).willReturn(expected);
when(original.getCode()).thenReturn(expected);

// Then
assertThat(wrapped.getCode()).isSameAs(expected);
Expand All @@ -178,7 +179,7 @@ void getMessageDelegates() {
var stack = someStackTraceList();
var wrapped = new TraceDiagnostic<>(now(), 123, "foo", stack, original);
var message = UUID.randomUUID().toString();
given(original.getMessage(any())).willReturn(message);
when(original.getMessage(any())).thenReturn(message);

// Then
assertThat(wrapped.getMessage(Locale.TAIWAN)).isSameAs(message);
Expand All @@ -190,7 +191,7 @@ void getMessageDelegates() {
void nullTimestampsAreRejected() {
var diag = someDiagnostic();
var stack = someStackTraceList();
thenCode(() -> new TraceDiagnostic<>(null, 123, "foo", stack, diag))
assertThatThrownBy(() -> new TraceDiagnostic<>(null, 123, "foo", stack, diag))
.isInstanceOf(NullPointerException.class)
.hasMessage("timestamp");
}
Expand All @@ -200,7 +201,7 @@ void nullTimestampsAreRejected() {
void nullStackTracesAreRejected() {
var now = now();
var diag = someDiagnostic();
thenCode(() -> new TraceDiagnostic<>(now, 123, "foo", null, diag))
assertThatThrownBy(() -> new TraceDiagnostic<>(now, 123, "foo", null, diag))
.isInstanceOf(NullPointerException.class)
.hasMessage("stackTrace");
}
Expand All @@ -222,7 +223,7 @@ void getTimestampReturnsTheTimestamp() {
var actualTimestamp = diagnostic.getTimestamp();

// Then
then(actualTimestamp).isEqualTo(expectedTimestamp);
assertThat(actualTimestamp).isEqualTo(expectedTimestamp);
}

@DisplayName("getThreadId() returns the thread ID")
Expand All @@ -242,7 +243,7 @@ void getThreadIdReturnsTheThreadId() {
var actualThreadId = diagnostic.getThreadId();

// Then
then(actualThreadId).isEqualTo(expectedThreadId);
assertThat(actualThreadId).isEqualTo(expectedThreadId);
}

@DisplayName("getThreadName() returns the thread name when known")
Expand All @@ -262,7 +263,7 @@ void getThreadNameReturnsTheThreadNameWhenKnown() {
var actualThreadName = diagnostic.getThreadName();

// Then
then(actualThreadName).isPresent().contains(expectedThreadName);
assertThat(actualThreadName).isPresent().contains(expectedThreadName);
}

@DisplayName("getThreadName() returns empty when the thread name is not known")
Expand All @@ -281,7 +282,7 @@ void getThreadNameReturnsEmptyWhenTheThreadNameIsNotKnown() {
var actualThreadName = diagnostic.getThreadName();

// Then
then(actualThreadName).isEmpty();
assertThat(actualThreadName).isEmpty();
}

@DisplayName("getStackTrace() returns the stack trace")
Expand All @@ -301,6 +302,26 @@ void getStackTraceReturnsTheStackTrace() {
var actualStackTrace = diagnostic.getStackTrace();

// Then
then(actualStackTrace).isSameAs(expectedStackTrace);
assertThat(actualStackTrace).isEqualTo(expectedStackTrace);
}

@DisplayName("getStackTrace() returns an immutable list")
@Test
void getStackTraceReturnsAnImmutableStackTrace() {
// Given
var expectedStackTrace = someStackTraceList();
var diagnostic = new TraceDiagnostic<>(
now(),
1234,
"foo",
expectedStackTrace,
someDiagnostic()
);

var actualStackTrace = diagnostic.getStackTrace();

// Then
assertThatThrownBy(() -> actualStackTrace.remove(0))
.isInstanceOf(UnsupportedOperationException.class);
}
}