| /* |
| * Copyright (c) 2011 Google, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.google.common.truth; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| |
| import com.google.common.annotations.GwtIncompatible; |
| import com.google.common.base.Optional; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Multimap; |
| import com.google.common.collect.Multiset; |
| import com.google.common.collect.Table; |
| import com.google.common.util.concurrent.AtomicLongMap; |
| import java.math.BigDecimal; |
| import java.util.Map; |
| import org.checkerframework.checker.nullness.compatqual.NullableDecl; |
| |
| /*>>>import org.checkerframework.checker.nullness.compatcompatqual.NullableDeclType;*/ |
| |
| /** |
| * In a fluent assertion chain, an object with which you can do any of the following: |
| * |
| * <ul> |
| * <li>Set an optional message with {@link #withMessage}. |
| * <li>Specify the type of {@code Subject} to create with {@link #about(Subject.Factory)}. |
| * <li>For the types of {@code Subject} built into Truth, directly specify the value under test |
| * with {@link #that(Object)}. |
| * </ul> |
| * |
| * <p>For more information about the methods in this class, see <a |
| * href="https://truth.dev/faq#full-chain">this FAQ entry</a>. |
| * |
| * <h3>For people extending Truth</h3> |
| * |
| * <p>You won't extend this type. When you write a custom subject, see <a |
| * href="https://truth.dev/extension">our doc on extensions</a>. |
| */ |
| public class StandardSubjectBuilder { |
| /** |
| * Returns a new instance that invokes the given {@code FailureStrategy} when a check fails. Most |
| * users should not need this. If you think you do, see the documentation on {@link |
| * FailureStrategy}. |
| */ |
| public static StandardSubjectBuilder forCustomFailureStrategy(FailureStrategy failureStrategy) { |
| return new StandardSubjectBuilder(FailureMetadata.forFailureStrategy(failureStrategy)); |
| } |
| |
| private final FailureMetadata metadataDoNotReferenceDirectly; |
| |
| StandardSubjectBuilder(FailureMetadata metadata) { |
| this.metadataDoNotReferenceDirectly = checkNotNull(metadata); |
| } |
| |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| public final <ComparableT extends Comparable<?>> ComparableSubject<ComparableT> that( |
| @NullableDecl ComparableT actual) { |
| return new ComparableSubject(metadata(), actual) {}; |
| } |
| |
| public final BigDecimalSubject that(@NullableDecl BigDecimal actual) { |
| return new BigDecimalSubject(metadata(), actual); |
| } |
| |
| public final Subject that(@NullableDecl Object actual) { |
| return new Subject(metadata(), actual); |
| } |
| |
| @GwtIncompatible("ClassSubject.java") |
| public final ClassSubject that(@NullableDecl Class<?> actual) { |
| return new ClassSubject(metadata(), actual); |
| } |
| |
| public final ThrowableSubject that(@NullableDecl Throwable actual) { |
| return new ThrowableSubject(metadata(), actual, "throwable"); |
| } |
| |
| public final LongSubject that(@NullableDecl Long actual) { |
| return new LongSubject(metadata(), actual); |
| } |
| |
| public final DoubleSubject that(@NullableDecl Double actual) { |
| return new DoubleSubject(metadata(), actual); |
| } |
| |
| public final FloatSubject that(@NullableDecl Float actual) { |
| return new FloatSubject(metadata(), actual); |
| } |
| |
| public final IntegerSubject that(@NullableDecl Integer actual) { |
| return new IntegerSubject(metadata(), actual); |
| } |
| |
| public final BooleanSubject that(@NullableDecl Boolean actual) { |
| return new BooleanSubject(metadata(), actual); |
| } |
| |
| public final StringSubject that(@NullableDecl String actual) { |
| return new StringSubject(metadata(), actual); |
| } |
| |
| public final IterableSubject that(@NullableDecl Iterable<?> actual) { |
| return new IterableSubject(metadata(), actual); |
| } |
| |
| public final <T> ObjectArraySubject<T> that(@NullableDecl T[] actual) { |
| return new ObjectArraySubject<>(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveBooleanArraySubject that(@NullableDecl boolean[] actual) { |
| return new PrimitiveBooleanArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveShortArraySubject that(@NullableDecl short[] actual) { |
| return new PrimitiveShortArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveIntArraySubject that(@NullableDecl int[] actual) { |
| return new PrimitiveIntArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveLongArraySubject that(@NullableDecl long[] actual) { |
| return new PrimitiveLongArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveCharArraySubject that(@NullableDecl char[] actual) { |
| return new PrimitiveCharArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveByteArraySubject that(@NullableDecl byte[] actual) { |
| return new PrimitiveByteArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveFloatArraySubject that(@NullableDecl float[] actual) { |
| return new PrimitiveFloatArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final PrimitiveDoubleArraySubject that(@NullableDecl double[] actual) { |
| return new PrimitiveDoubleArraySubject(metadata(), actual, "array"); |
| } |
| |
| public final GuavaOptionalSubject that(@NullableDecl Optional<?> actual) { |
| return new GuavaOptionalSubject(metadata(), actual, "optional"); |
| } |
| |
| public final MapSubject that(@NullableDecl Map<?, ?> actual) { |
| return new MapSubject(metadata(), actual); |
| } |
| |
| public final MultimapSubject that(@NullableDecl Multimap<?, ?> actual) { |
| return new MultimapSubject(metadata(), actual, "multimap"); |
| } |
| |
| public final MultisetSubject that(@NullableDecl Multiset<?> actual) { |
| return new MultisetSubject(metadata(), actual); |
| } |
| |
| public final TableSubject that(@NullableDecl Table<?, ?, ?> actual) { |
| return new TableSubject(metadata(), actual); |
| } |
| |
| /** @deprecated Perform assertions on the {@link AtomicLongMap#asMap()} view. */ |
| @Deprecated |
| public final AtomicLongMapSubject that(@NullableDecl AtomicLongMap<?> actual) { |
| return new AtomicLongMapSubject(metadata(), actual); |
| } |
| |
| /** |
| * Returns a new instance that will output the given message before the main failure message. If |
| * this method is called multiple times, the messages will appear in the order that they were |
| * specified. |
| */ |
| public final StandardSubjectBuilder withMessage(@NullableDecl String messageToPrepend) { |
| return withMessage("%s", messageToPrepend); |
| } |
| |
| /** |
| * Returns a new instance that will output the given message before the main failure message. If |
| * this method is called multiple times, the messages will appear in the order that they were |
| * specified. |
| * |
| * <p><b>Note:</b> the arguments will be substituted into the format template using {@link |
| * com.google.common.base.Strings#lenientFormat Strings.lenientFormat}. Note this only supports |
| * the {@code %s} specifier. |
| * |
| * @throws IllegalArgumentException if the number of placeholders in the format string does not |
| * equal the number of given arguments |
| */ |
| public final StandardSubjectBuilder withMessage( |
| String format, Object /* @NullableDeclType */... args) { |
| return new StandardSubjectBuilder(metadata().withMessage(format, args)); |
| } |
| |
| /** |
| * Given a factory for some {@code Subject} class, returns a builder whose {@code that(actual)} |
| * method creates instances of that class. Created subjects use the previously set failure |
| * strategy and any previously set failure message. |
| */ |
| public final <S extends Subject, A> SimpleSubjectBuilder<S, A> about( |
| Subject.Factory<S, A> factory) { |
| return new SimpleSubjectBuilder<>(metadata(), factory); |
| } |
| |
| public final <CustomSubjectBuilderT extends CustomSubjectBuilder> CustomSubjectBuilderT about( |
| CustomSubjectBuilder.Factory<CustomSubjectBuilderT> factory) { |
| return factory.createSubjectBuilder(metadata()); |
| } |
| |
| /** |
| * Reports a failure. |
| * |
| * <p>To set a message, first call {@link #withMessage} (or, more commonly, use the shortcut |
| * {@link Truth#assertWithMessage}). |
| */ |
| public final void fail() { |
| metadata().fail(ImmutableList.<Fact>of()); |
| } |
| |
| /** |
| * Reports a failure with the given message. |
| * |
| * @deprecated Instead of {@code assert_().fail(...)}, use {@code assertWithMessage(...).fail()}. |
| * Similarly, instead of {@code expect.fail(...)}, use {@code expect.withMessage(...).fail()}, |
| * and so forth. |
| */ |
| @Deprecated |
| public final void fail(String format, Object /*@NullableDeclType*/... args) { |
| withMessage(format, args).fail(); |
| } |
| |
| private FailureMetadata metadata() { |
| checkStatePreconditions(); |
| return metadataDoNotReferenceDirectly; |
| } |
| |
| /** |
| * Extension point invoked before every assertion. This allows {@link Expect} to check that it's |
| * been set up properly as a {@code TestRule}. |
| */ |
| void checkStatePreconditions() {} |
| } |