001/* 002 * Copyright (C) 2022 - 2024, the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.github.ascopes.jct.assertions; 017 018import static java.util.Objects.requireNonNull; 019import static org.assertj.core.api.Assertions.assertThat; 020 021import io.github.ascopes.jct.diagnostics.TraceDiagnostic; 022import io.github.ascopes.jct.repr.TraceDiagnosticRepresentation; 023import java.util.Locale; 024import javax.tools.JavaFileObject; 025import org.assertj.core.api.AbstractAssert; 026import org.assertj.core.api.AbstractInstantAssert; 027import org.assertj.core.api.AbstractLongAssert; 028import org.assertj.core.api.AbstractStringAssert; 029import org.jspecify.annotations.Nullable; 030 031/** 032 * Assertions for an individual {@link TraceDiagnostic trace diagnostic}. 033 * 034 * @author Ashley Scopes 035 * @since 0.0.1 036 */ 037public final class TraceDiagnosticAssert 038 extends AbstractAssert<TraceDiagnosticAssert, TraceDiagnostic<? extends JavaFileObject>> { 039 040 /** 041 * Initialize this assertion type. 042 * 043 * @param value the value to assert on. 044 */ 045 @SuppressWarnings("DataFlowIssue") 046 public TraceDiagnosticAssert(@Nullable TraceDiagnostic<? extends JavaFileObject> value) { 047 super(value, TraceDiagnosticAssert.class); 048 info.useRepresentation(TraceDiagnosticRepresentation.getInstance()); 049 } 050 051 /** 052 * Get assertions for the kind of the diagnostic. 053 * 054 * @return the assertions for the diagnostic kind. 055 * @throws AssertionError if the diagnostic is null. 056 */ 057 public DiagnosticKindAssert kind() { 058 isNotNull(); 059 060 return new DiagnosticKindAssert(actual.getKind()); 061 } 062 063 /** 064 * Get assertions for the source of the diagnostic. 065 * 066 * <p>If no source is present, then the value in the returned assertions may be {@code null}. 067 * 068 * @return the assertions for the source of the diagnostic. 069 * @throws AssertionError if the diagnostic is null. 070 */ 071 public JavaFileObjectAssert source() { 072 isNotNull(); 073 074 return new JavaFileObjectAssert(actual.getSource()); 075 } 076 077 /** 078 * Get assertions for the position of the diagnostic. 079 * 080 * <p>The value may be -1 if no information is available. 081 * 082 * @return the assertions for the position of the diagnostic. 083 * @throws AssertionError if the diagnostic is null. 084 */ 085 public AbstractLongAssert<?> position() { 086 isNotNull(); 087 088 return assertThat(actual.getPosition()).describedAs("position"); 089 } 090 091 /** 092 * Get assertions for the start position of the diagnostic. 093 * 094 * <p>The value may be -1 if no information is available. 095 * 096 * @return the assertions for the start position of the diagnostic. 097 * @throws AssertionError if the diagnostic is null. 098 */ 099 public AbstractLongAssert<?> startPosition() { 100 isNotNull(); 101 102 return assertThat(actual.getStartPosition()).describedAs("start position"); 103 } 104 105 /** 106 * Get assertions for the end position of the diagnostic. 107 * 108 * <p>The value may be -1 if no information is available. 109 * 110 * @return the assertions for the end position of the diagnostic. 111 * @throws AssertionError if the diagnostic is null. 112 */ 113 public AbstractLongAssert<?> endPosition() { 114 isNotNull(); 115 116 return assertThat(actual.getEndPosition()).describedAs("end position"); 117 } 118 119 /** 120 * Get assertions for the line number of the diagnostic. 121 * 122 * <p>The value may be -1 if no information is available. 123 * 124 * @return the assertions for the line number of the diagnostic. 125 * @throws AssertionError if the diagnostic is null. 126 */ 127 public AbstractLongAssert<?> lineNumber() { 128 isNotNull(); 129 130 return assertThat(actual.getLineNumber()).describedAs("line number"); 131 } 132 133 /** 134 * Get assertions for the column number of the diagnostic. 135 * 136 * <p>The value may be -1 if no information is available. 137 * 138 * @return the assertions for the column number of the diagnostic. 139 * @throws AssertionError if the diagnostic is null. 140 */ 141 public AbstractLongAssert<?> columnNumber() { 142 isNotNull(); 143 144 return assertThat(actual.getColumnNumber()).describedAs("column number"); 145 } 146 147 /** 148 * Get assertions for the code of the diagnostic. 149 * 150 * @return the assertions for the code of the diagnostic. 151 * @throws AssertionError if the diagnostic is null. 152 */ 153 public AbstractStringAssert<?> code() { 154 isNotNull(); 155 156 return assertThat(actual.getCode()).describedAs("code"); 157 } 158 159 /** 160 * Get assertions for the message of the diagnostic, assuming the default locale. 161 * 162 * @return the assertions for the message of the diagnostic. 163 * @throws AssertionError if the diagnostic is null. 164 */ 165 public AbstractStringAssert<?> message() { 166 isNotNull(); 167 168 return assertThat(actual.getMessage(null)); 169 } 170 171 /** 172 * Get assertions for the message of the diagnostic. 173 * 174 * @param locale the locale to use. 175 * @return the assertions for the message of the diagnostic. 176 * @throws AssertionError if the diagnostic is null. 177 */ 178 public AbstractStringAssert<?> message(Locale locale) { 179 requireNonNull(locale, "locale must not be null"); 180 181 isNotNull(); 182 183 return assertThat(actual.getMessage(locale)); 184 } 185 186 /** 187 * Get assertions for the timestamp of the diagnostic. 188 * 189 * @return the assertions for the timestamp of the diagnostic. 190 * @throws AssertionError if the diagnostic is null. 191 */ 192 public AbstractInstantAssert<?> timestamp() { 193 isNotNull(); 194 195 return assertThat(actual.getTimestamp()); 196 } 197 198 /** 199 * Get assertions for the thread ID of the thread that reported the diagnostic to the compiler. 200 * 201 * @return the assertions for the thread ID. 202 * @throws AssertionError if the diagnostic is null. 203 */ 204 public AbstractLongAssert<?> threadId() { 205 isNotNull(); 206 207 return assertThat(actual.getThreadId()); 208 } 209 210 /** 211 * Get assertions for the thread name of the thread that reported the diagnostic. 212 * 213 * <p>This may not be present in some situations, in which case the returned assertions will be 214 * performed on a null value instead. 215 * 216 * @return the assertions for the thread name. 217 * @throws AssertionError if the diagnostic is null. 218 */ 219 public AbstractStringAssert<?> threadName() { 220 isNotNull(); 221 222 return assertThat(actual.getThreadName()); 223 } 224 225 /** 226 * Get assertions for the stack trace of the location the diagnostic was reported to. 227 * 228 * @return the assertions for the stack trace. 229 * @throws AssertionError if the diagnostic is null. 230 */ 231 public StackTraceAssert stackTrace() { 232 isNotNull(); 233 234 return new StackTraceAssert(actual.getStackTrace()); 235 } 236}