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 org.assertj.core.api.Assertions.assertThat;
019
020import org.assertj.core.api.AbstractAssert;
021import org.assertj.core.api.AbstractBooleanAssert;
022import org.assertj.core.api.AbstractIntegerAssert;
023import org.assertj.core.api.AbstractStringAssert;
024import org.jspecify.annotations.Nullable;
025
026/**
027 * Assertions to perform on a {@link StackTraceElement stack trace frame}.
028 *
029 * @author Ashley Scopes
030 * @since 0.0.1
031 */
032public final class StackTraceElementAssert
033    extends AbstractAssert<StackTraceElementAssert, StackTraceElement> {
034
035  /**
036   * Initialize this assertion object.
037   *
038   * @param actual the stacktrace element to assert upon.
039   */
040  @SuppressWarnings("DataFlowIssue")
041  public StackTraceElementAssert(@Nullable StackTraceElement actual) {
042    super(actual, StackTraceElementAssert.class);
043  }
044
045  /**
046   * Get assertions for the filename of the stack trace frame.
047   *
048   * @return the assertions for the file name.
049   * @throws AssertionError if the stack trace element is null.
050   */
051  public AbstractStringAssert<?> fileName() {
052    isNotNull();
053
054    return assertThat(actual.getFileName())
055        .as("file name");
056  }
057
058  /**
059   * Get assertions for the line number of the stack trace frame.
060   *
061   * <p>The line number may be non-positive if the method is a
062   * {@link #nativeMethod() native method}.
063   *
064   * @return the assertions for the line number.
065   * @throws AssertionError if the stack trace element is null.
066   */
067  public AbstractIntegerAssert<?> lineNumber() {
068    isNotNull();
069
070    return assertThat(actual.getLineNumber())
071        .as("line number");
072  }
073
074  /**
075   * Get assertions for the module name of the stack trace frame.
076   *
077   * <p>The value may be null if not present.
078   *
079   * @return the assertions for the module name.
080   * @throws AssertionError if the stack trace element is null.
081   */
082  public AbstractStringAssert<?> moduleName() {
083    isNotNull();
084
085    return assertThat(actual.getModuleName())
086        .as("module name");
087  }
088
089  /**
090   * Get assertions for the module version of the stack trace frame.
091   *
092   * <p>The value may be null if not present.
093   *
094   * @return the assertions for the module version.
095   * @throws AssertionError if the stack trace element is null.
096   */
097  public AbstractStringAssert<?> moduleVersion() {
098    isNotNull();
099
100    return assertThat(actual.getModuleVersion())
101        .as("module version");
102  }
103
104  /**
105   * Get assertions for the name of the classloader of the class in the stack trace frame.
106   *
107   * @return the assertions for the classloader name.
108   * @throws AssertionError if the stack trace element is null.
109   */
110  public AbstractStringAssert<?> classLoaderName() {
111    isNotNull();
112
113    return assertThat(actual.getClassLoaderName())
114        .as("class loader name");
115  }
116
117  /**
118   * Get assertions for the class name of the stack trace frame.
119   *
120   * @return the assertions for the class name.
121   * @throws AssertionError if the stack trace element is null.
122   */
123  public AbstractStringAssert<?> className() {
124    isNotNull();
125
126    return assertThat(actual.getClassName())
127        .as("class name");
128  }
129
130  /**
131   * Get assertions for the method name of the stack trace frame.
132   *
133   * @return the assertions for the method name.
134   * @throws AssertionError if the stack trace element is null.
135   */
136  public AbstractStringAssert<?> methodName() {
137    isNotNull();
138
139    return assertThat(actual.getMethodName())
140        .as("method name");
141  }
142
143  /**
144   * Get assertions for whether the frame is for a native (JNI) method or not.
145   *
146   * @return the assertions for the method nativity.
147   * @throws AssertionError if the stack trace element is null.
148   */
149  public AbstractBooleanAssert<?> nativeMethod() {
150    isNotNull();
151
152    return assertThat(actual.isNativeMethod())
153        .as("native method");
154  }
155}