• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011 Google, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.common.truth;
17 
18 import static com.google.common.base.Preconditions.checkNotNull;
19 
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.base.Optional;
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.Multimap;
24 import com.google.common.collect.Multiset;
25 import com.google.common.collect.Table;
26 import java.math.BigDecimal;
27 import java.util.Map;
28 import org.checkerframework.checker.nullness.qual.Nullable;
29 
30 /**
31  * In a fluent assertion chain, an object with which you can do any of the following:
32  *
33  * <ul>
34  *   <li>Set an optional message with {@link #withMessage}.
35  *   <li>Specify the type of {@code Subject} to create with {@link #about(Subject.Factory)}.
36  *   <li>For the types of {@code Subject} built into Truth, directly specify the value under test
37  *       with {@link #that(Object)}.
38  * </ul>
39  *
40  * <p>For more information about the methods in this class, see <a
41  * href="https://truth.dev/faq#full-chain">this FAQ entry</a>.
42  *
43  * <h3>For people extending Truth</h3>
44  *
45  * <p>You won't extend this type. When you write a custom subject, see <a
46  * href="https://truth.dev/extension">our doc on extensions</a>.
47  */
48 public class StandardSubjectBuilder {
49   /**
50    * Returns a new instance that invokes the given {@code FailureStrategy} when a check fails. Most
51    * users should not need this. If you think you do, see the documentation on {@link
52    * FailureStrategy}.
53    */
forCustomFailureStrategy(FailureStrategy failureStrategy)54   public static StandardSubjectBuilder forCustomFailureStrategy(FailureStrategy failureStrategy) {
55     return new StandardSubjectBuilder(FailureMetadata.forFailureStrategy(failureStrategy));
56   }
57 
58   private final FailureMetadata metadataDoNotReferenceDirectly;
59 
StandardSubjectBuilder(FailureMetadata metadata)60   StandardSubjectBuilder(FailureMetadata metadata) {
61     this.metadataDoNotReferenceDirectly = checkNotNull(metadata);
62   }
63 
64   @SuppressWarnings({"unchecked", "rawtypes"})
that( @ullable ComparableT actual)65   public final <ComparableT extends Comparable<?>> ComparableSubject<ComparableT> that(
66       @Nullable ComparableT actual) {
67     return new ComparableSubject(metadata(), actual) {};
68   }
69 
that(@ullable BigDecimal actual)70   public final BigDecimalSubject that(@Nullable BigDecimal actual) {
71     return new BigDecimalSubject(metadata(), actual);
72   }
73 
that(@ullable Object actual)74   public final Subject that(@Nullable Object actual) {
75     return new Subject(metadata(), actual);
76   }
77 
78   @GwtIncompatible("ClassSubject.java")
that(@ullable Class<?> actual)79   public final ClassSubject that(@Nullable Class<?> actual) {
80     return new ClassSubject(metadata(), actual);
81   }
82 
that(@ullable Throwable actual)83   public final ThrowableSubject that(@Nullable Throwable actual) {
84     return new ThrowableSubject(metadata(), actual, "throwable");
85   }
86 
that(@ullable Long actual)87   public final LongSubject that(@Nullable Long actual) {
88     return new LongSubject(metadata(), actual);
89   }
90 
that(@ullable Double actual)91   public final DoubleSubject that(@Nullable Double actual) {
92     return new DoubleSubject(metadata(), actual);
93   }
94 
that(@ullable Float actual)95   public final FloatSubject that(@Nullable Float actual) {
96     return new FloatSubject(metadata(), actual);
97   }
98 
that(@ullable Integer actual)99   public final IntegerSubject that(@Nullable Integer actual) {
100     return new IntegerSubject(metadata(), actual);
101   }
102 
that(@ullable Boolean actual)103   public final BooleanSubject that(@Nullable Boolean actual) {
104     return new BooleanSubject(metadata(), actual);
105   }
106 
that(@ullable String actual)107   public final StringSubject that(@Nullable String actual) {
108     return new StringSubject(metadata(), actual);
109   }
110 
that(@ullable Iterable<?> actual)111   public final IterableSubject that(@Nullable Iterable<?> actual) {
112     return new IterableSubject(metadata(), actual);
113   }
114 
that(@ullable T [] actual)115   public final <T> ObjectArraySubject<T> that(@Nullable T /*@Nullable*/[] actual) {
116     return new ObjectArraySubject<>(metadata(), actual, "array");
117   }
118 
that(boolean [] actual)119   public final PrimitiveBooleanArraySubject that(boolean /*@Nullable*/[] actual) {
120     return new PrimitiveBooleanArraySubject(metadata(), actual, "array");
121   }
122 
that(short [] actual)123   public final PrimitiveShortArraySubject that(short /*@Nullable*/[] actual) {
124     return new PrimitiveShortArraySubject(metadata(), actual, "array");
125   }
126 
that(int [] actual)127   public final PrimitiveIntArraySubject that(int /*@Nullable*/[] actual) {
128     return new PrimitiveIntArraySubject(metadata(), actual, "array");
129   }
130 
that(long [] actual)131   public final PrimitiveLongArraySubject that(long /*@Nullable*/[] actual) {
132     return new PrimitiveLongArraySubject(metadata(), actual, "array");
133   }
134 
that(char [] actual)135   public final PrimitiveCharArraySubject that(char /*@Nullable*/[] actual) {
136     return new PrimitiveCharArraySubject(metadata(), actual, "array");
137   }
138 
that(byte [] actual)139   public final PrimitiveByteArraySubject that(byte /*@Nullable*/[] actual) {
140     return new PrimitiveByteArraySubject(metadata(), actual, "array");
141   }
142 
that(float [] actual)143   public final PrimitiveFloatArraySubject that(float /*@Nullable*/[] actual) {
144     return new PrimitiveFloatArraySubject(metadata(), actual, "array");
145   }
146 
that(double [] actual)147   public final PrimitiveDoubleArraySubject that(double /*@Nullable*/[] actual) {
148     return new PrimitiveDoubleArraySubject(metadata(), actual, "array");
149   }
150 
that(@ullable Optional<?> actual)151   public final GuavaOptionalSubject that(@Nullable Optional<?> actual) {
152     return new GuavaOptionalSubject(metadata(), actual, "optional");
153   }
154 
that(@ullable Map<?, ?> actual)155   public final MapSubject that(@Nullable Map<?, ?> actual) {
156     return new MapSubject(metadata(), actual);
157   }
158 
that(@ullable Multimap<?, ?> actual)159   public final MultimapSubject that(@Nullable Multimap<?, ?> actual) {
160     return new MultimapSubject(metadata(), actual, "multimap");
161   }
162 
that(@ullable Multiset<?> actual)163   public final MultisetSubject that(@Nullable Multiset<?> actual) {
164     return new MultisetSubject(metadata(), actual);
165   }
166 
that(@ullable Table<?, ?, ?> actual)167   public final TableSubject that(@Nullable Table<?, ?, ?> actual) {
168     return new TableSubject(metadata(), actual);
169   }
170 
171   /**
172    * Returns a new instance that will output the given message before the main failure message. If
173    * this method is called multiple times, the messages will appear in the order that they were
174    * specified.
175    */
withMessage(@ullable String messageToPrepend)176   public final StandardSubjectBuilder withMessage(@Nullable String messageToPrepend) {
177     return withMessage("%s", messageToPrepend);
178   }
179 
180   /**
181    * Returns a new instance that will output the given message before the main failure message. If
182    * this method is called multiple times, the messages will appear in the order that they were
183    * specified.
184    *
185    * <p><b>Note:</b> the arguments will be substituted into the format template using {@link
186    * com.google.common.base.Strings#lenientFormat Strings.lenientFormat}. Note this only supports
187    * the {@code %s} specifier.
188    *
189    * @throws IllegalArgumentException if the number of placeholders in the format string does not
190    *     equal the number of given arguments
191    */
withMessage(String format, Object... args)192   public final StandardSubjectBuilder withMessage(String format, /*@Nullable*/ Object... args) {
193     return new StandardSubjectBuilder(metadata().withMessage(format, args));
194   }
195 
196   /**
197    * Given a factory for some {@code Subject} class, returns a builder whose {@code that(actual)}
198    * method creates instances of that class. Created subjects use the previously set failure
199    * strategy and any previously set failure message.
200    */
about( Subject.Factory<S, A> factory)201   public final <S extends Subject, A> SimpleSubjectBuilder<S, A> about(
202       Subject.Factory<S, A> factory) {
203     return new SimpleSubjectBuilder<>(metadata(), factory);
204   }
205 
about( CustomSubjectBuilder.Factory<CustomSubjectBuilderT> factory)206   public final <CustomSubjectBuilderT extends CustomSubjectBuilder> CustomSubjectBuilderT about(
207       CustomSubjectBuilder.Factory<CustomSubjectBuilderT> factory) {
208     return factory.createSubjectBuilder(metadata());
209   }
210 
211   /**
212    * Reports a failure.
213    *
214    * <p>To set a message, first call {@link #withMessage} (or, more commonly, use the shortcut
215    * {@link Truth#assertWithMessage}).
216    */
fail()217   public final void fail() {
218     metadata().fail(ImmutableList.<Fact>of());
219   }
220 
metadata()221   private FailureMetadata metadata() {
222     checkStatePreconditions();
223     return metadataDoNotReferenceDirectly;
224   }
225 
226   /**
227    * Extension point invoked before every assertion. This allows {@link Expect} to check that it's
228    * been set up properly as a {@code TestRule}.
229    */
checkStatePreconditions()230   void checkStatePreconditions() {}
231 }
232