• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018 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 
17 package com.google.common.truth;
18 
19 import static com.google.common.truth.Fact.simpleFact;
20 import static com.google.common.truth.Truth.assertThat;
21 import static com.google.common.truth.Truth.assert_;
22 
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.JUnit4;
26 
27 /** Tests for chained subjects (produced with {@link Subject#check(String, Object...)}, etc.). */
28 @RunWith(JUnit4.class)
29 public final class ChainingTest extends BaseSubjectTestCase {
30   private static final Throwable throwable = new Throwable("root");
31 
32   @Test
noChaining()33   public void noChaining() {
34     expectFailureWhenTestingThat("root").isThePresentKingOfFrance();
35     assertNoCause("message");
36   }
37 
38   @Test
oneLevel()39   public void oneLevel() {
40     expectFailureWhenTestingThat("root").delegatingTo("child").isThePresentKingOfFrance();
41     assertNoCause("message");
42   }
43 
44   @Test
twoLevels()45   public void twoLevels() {
46     expectFailureWhenTestingThat("root")
47         .delegatingTo("child")
48         .delegatingTo("grandchild")
49         .isThePresentKingOfFrance();
50     assertNoCause("message");
51   }
52 
53   @Test
noChainingRootThrowable()54   public void noChainingRootThrowable() {
55     expectFailureWhenTestingThat(throwable).isThePresentKingOfFrance();
56     assertHasCause("message");
57   }
58 
59   @Test
oneLevelRootThrowable()60   public void oneLevelRootThrowable() {
61     expectFailureWhenTestingThat(throwable).delegatingTo("child").isThePresentKingOfFrance();
62     assertHasCause("message");
63   }
64 
65   @Test
twoLevelsRootThrowable()66   public void twoLevelsRootThrowable() {
67     expectFailureWhenTestingThat(throwable)
68         .delegatingTo("child")
69         .delegatingTo("grandchild")
70         .isThePresentKingOfFrance();
71     assertHasCause("message");
72   }
73 
74   // e.g., future.failureCause()
75   @Test
oneLevelDerivedThrowable()76   public void oneLevelDerivedThrowable() {
77     expectFailureWhenTestingThat("root").delegatingTo(throwable).isThePresentKingOfFrance();
78     assertHasCause("message");
79   }
80 
81   @Test
twoLevelsDerivedThrowableMiddle()82   public void twoLevelsDerivedThrowableMiddle() {
83     expectFailureWhenTestingThat("root")
84         .delegatingTo(throwable)
85         .delegatingTo("grandchild")
86         .isThePresentKingOfFrance();
87     assertHasCause("message");
88   }
89 
90   @Test
twoLevelsDerivedThrowableLast()91   public void twoLevelsDerivedThrowableLast() {
92     expectFailureWhenTestingThat("root")
93         .delegatingTo("child")
94         .delegatingTo(throwable)
95         .isThePresentKingOfFrance();
96     assertHasCause("message");
97   }
98 
99   @Test
oneLevelNamed()100   public void oneLevelNamed() {
101     expectFailureWhenTestingThat("root")
102         .delegatingToNamed("child", "child")
103         .isThePresentKingOfFrance();
104     assertNoCause("value of    : myObject.child\nmessage\nmyObject was: root");
105   }
106 
107   @Test
twoLevelsNamed()108   public void twoLevelsNamed() {
109     expectFailureWhenTestingThat("root")
110         .delegatingToNamed("child", "child")
111         .delegatingToNamed("grandchild", "grandchild")
112         .isThePresentKingOfFrance();
113     assertNoCause("value of    : myObject.child.grandchild\nmessage\nmyObject was: root");
114   }
115 
116   @Test
twoLevelsOnlyFirstNamed()117   public void twoLevelsOnlyFirstNamed() {
118     expectFailureWhenTestingThat("root")
119         .delegatingToNamed("child", "child")
120         .delegatingTo("grandchild")
121         .isThePresentKingOfFrance();
122     assertNoCause("message\nmyObject was: root");
123   }
124 
125   @Test
twoLevelsOnlySecondNamed()126   public void twoLevelsOnlySecondNamed() {
127     expectFailureWhenTestingThat("root")
128         .delegatingTo("child")
129         .delegatingToNamed("grandchild", "grandchild")
130         .isThePresentKingOfFrance();
131     assertNoCause("value of    : myObject.grandchild\nmessage\nmyObject was: root");
132   }
133 
134   @Test
oneLevelNamedNoNeedToDisplayBoth()135   public void oneLevelNamedNoNeedToDisplayBoth() {
136     expectFailureWhenTestingThat("root")
137         .delegatingToNamedNoNeedToDisplayBoth("child", "child")
138         .isThePresentKingOfFrance();
139     assertNoCause("value of: myObject.child\nmessage");
140   }
141 
142   @Test
twoLevelsNamedNoNeedToDisplayBoth()143   public void twoLevelsNamedNoNeedToDisplayBoth() {
144     expectFailureWhenTestingThat("root")
145         .delegatingToNamedNoNeedToDisplayBoth("child", "child")
146         .delegatingToNamedNoNeedToDisplayBoth("grandchild", "grandchild")
147         .isThePresentKingOfFrance();
148     assertNoCause("value of: myObject.child.grandchild\nmessage");
149   }
150 
151   @Test
twoLevelsOnlyFirstNamedNoNeedToDisplayBoth()152   public void twoLevelsOnlyFirstNamedNoNeedToDisplayBoth() {
153     expectFailureWhenTestingThat("root")
154         .delegatingToNamedNoNeedToDisplayBoth("child", "child")
155         .delegatingTo("grandchild")
156         .isThePresentKingOfFrance();
157     assertNoCause("message");
158   }
159 
160   @Test
twoLevelsOnlySecondNamedNoNeedToDisplayBoth()161   public void twoLevelsOnlySecondNamedNoNeedToDisplayBoth() {
162     expectFailureWhenTestingThat("root")
163         .delegatingTo("child")
164         .delegatingToNamedNoNeedToDisplayBoth("grandchild", "grandchild")
165         .isThePresentKingOfFrance();
166     assertNoCause("value of: myObject.grandchild\nmessage");
167   }
168 
169   @Test
twoLevelsNamedOnlyFirstNoNeedToDisplayBoth()170   public void twoLevelsNamedOnlyFirstNoNeedToDisplayBoth() {
171     expectFailureWhenTestingThat("root")
172         .delegatingToNamedNoNeedToDisplayBoth("child", "child")
173         .delegatingToNamed("grandchild", "grandchild")
174         .isThePresentKingOfFrance();
175     assertNoCause("value of    : myObject.child.grandchild\nmessage\nmyObject was: root");
176   }
177 
178   @Test
twoLevelsNamedOnlySecondNoNeedToDisplayBoth()179   public void twoLevelsNamedOnlySecondNoNeedToDisplayBoth() {
180     expectFailureWhenTestingThat("root")
181         .delegatingToNamed("child", "child")
182         .delegatingToNamedNoNeedToDisplayBoth("grandchild", "grandchild")
183         .isThePresentKingOfFrance();
184     assertNoCause("value of    : myObject.child.grandchild\nmessage\nmyObject was: root");
185   }
186 
187   @Test
namedAndMessage()188   public void namedAndMessage() {
189     expectFailure
190         .whenTesting()
191         .withMessage("prefix")
192         .about(myObjects())
193         .that("root")
194         .delegatingToNamed("child", "child")
195         .isThePresentKingOfFrance();
196     assertNoCause("prefix\nvalue of    : myObject.child\nmessage\nmyObject was: root");
197   }
198 
199   @Test
checkFail()200   public void checkFail() {
201     expectFailureWhenTestingThat("root").doCheckFail();
202     assertNoCause("message");
203   }
204 
205   @Test
checkFailWithName()206   public void checkFailWithName() {
207     expectFailureWhenTestingThat("root").doCheckFail("child");
208     assertNoCause("message\nvalue of    : myObject.child\nmyObject was: root");
209   }
210 
211   @Test
badFormat()212   public void badFormat() {
213     try {
214       @SuppressWarnings("LenientFormatStringValidation") // Intentional for testing.
215       Object unused = assertThat("root").check("%s %s", 1, 2, 3);
216       assert_().fail();
217     } catch (IllegalArgumentException expected) {
218     }
219   }
220 
221   /*
222    * TODO(cpovirk): It would be nice to have multiple Subject subclasses so that we know we're
223    * pulling the type from the right link in the chain. But we get some coverage of that from other
224    * tests like MultimapSubjectTest.
225    */
226 
227   private static final class MyObjectSubject extends Subject {
228     static final Factory<MyObjectSubject, Object> FACTORY =
229         new Factory<MyObjectSubject, Object>() {
230           @Override
231           public MyObjectSubject createSubject(FailureMetadata metadata, Object actual) {
232             return new MyObjectSubject(metadata, actual);
233           }
234         };
235 
MyObjectSubject(FailureMetadata metadata, Object actual)236     private MyObjectSubject(FailureMetadata metadata, Object actual) {
237       super(metadata, actual);
238     }
239 
240     /** Runs a check that always fails with the generic message "message." */
isThePresentKingOfFrance()241     void isThePresentKingOfFrance() {
242       failWithoutActual(simpleFact("message"));
243     }
244 
doCheckFail()245     void doCheckFail() {
246       check().withMessage("message").fail();
247     }
248 
doCheckFail(String name)249     void doCheckFail(String name) {
250       check(name).withMessage("message").fail();
251     }
252 
253     /**
254      * Returns a new {@code MyObjectSubject} for the given actual value, chaining it to the current
255      * subject with {@link Subject#check}.
256      */
delegatingTo(Object actual)257     MyObjectSubject delegatingTo(Object actual) {
258       return check().about(myObjects()).that(actual);
259     }
260 
261     /**
262      * Returns a new {@code MyObjectSubject} for the given actual value, chaining it to the current
263      * subject with {@link Subject#check}.
264      */
delegatingToNamed(Object actual, String name)265     MyObjectSubject delegatingToNamed(Object actual, String name) {
266       return check(name).about(myObjects()).that(actual);
267     }
268 
delegatingToNamedNoNeedToDisplayBoth(Object actual, String name)269     MyObjectSubject delegatingToNamedNoNeedToDisplayBoth(Object actual, String name) {
270       return checkNoNeedToDisplayBothValues(name).about(myObjects()).that(actual);
271     }
272   }
273 
myObjects()274   private static Subject.Factory<MyObjectSubject, Object> myObjects() {
275     return MyObjectSubject.FACTORY;
276   }
277 
expectFailureWhenTestingThat(Object actual)278   private MyObjectSubject expectFailureWhenTestingThat(Object actual) {
279     return expectFailure.whenTesting().about(myObjects()).that(actual);
280   }
281 
assertNoCause(String message)282   private void assertNoCause(String message) {
283     assertThatFailure().hasMessageThat().isEqualTo(message);
284     assertThatFailure().hasCauseThat().isNull();
285   }
286 
assertHasCause(String message)287   private void assertHasCause(String message) {
288     assertThatFailure().hasMessageThat().isEqualTo(message);
289     assertThatFailure().hasCauseThat().isEqualTo(throwable);
290   }
291 }
292