View Javadoc
1   /*
2    * Copyright 2011-2024 the original author or authors.
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    *         https://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.googlecode.catchexception.throwable.apis;
17  
18  import static com.googlecode.catchexception.throwable.CatchThrowable.catchThrowable;
19  import static com.googlecode.catchexception.throwable.CatchThrowable.caughtThrowable;
20  import static com.googlecode.catchexception.throwable.apis.CatchThrowableHamcrestMatchers.hasMessage;
21  import static com.googlecode.catchexception.throwable.apis.CatchThrowableHamcrestMatchers.hasMessageThat;
22  import static com.googlecode.catchexception.throwable.apis.CatchThrowableHamcrestMatchers.hasNoCause;
23  import static org.hamcrest.CoreMatchers.allOf;
24  import static org.hamcrest.CoreMatchers.containsString;
25  import static org.hamcrest.CoreMatchers.instanceOf;
26  import static org.hamcrest.CoreMatchers.is;
27  import static org.hamcrest.CoreMatchers.isA;
28  import static org.hamcrest.MatcherAssert.assertThat;
29  import static org.junit.jupiter.api.Assertions.assertEquals;
30  
31  import com.googlecode.catchexception.throwable.matcher.Find;
32  
33  import java.util.ArrayList;
34  import java.util.List;
35  
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * Tests {@link CatchThrowableHamcrestMatchers}.
41   */
42  class CatchThrowableHamcrestMatchersTest {
43  
44      /**
45       * The message of the exception thrown by {@code new ArrayList<String>().get(0) } for jdk9on.
46       */
47      private final String expectedMessageJdk9on = "Index 9 out of bounds for length 9";
48  
49      /**
50       * Setup.
51       */
52      @BeforeEach
53      void setup() {
54          List<String> fellowshipOfTheRing = new ArrayList<>();
55          // let's do some team building :)
56          fellowshipOfTheRing.add("frodo");
57          fellowshipOfTheRing.add("sam");
58          fellowshipOfTheRing.add("merry");
59          fellowshipOfTheRing.add("pippin");
60          fellowshipOfTheRing.add("gandalf");
61          fellowshipOfTheRing.add("legolas");
62          fellowshipOfTheRing.add("gimli");
63          fellowshipOfTheRing.add("aragorn");
64          fellowshipOfTheRing.add("boromir");
65  
66          catchThrowable(() -> fellowshipOfTheRing.get(9));
67      }
68  
69      /**
70       * Assert message.
71       *
72       * @param foundMessage
73       *            the found message
74       * @param expectedExpectedPart
75       *            the expected expected part
76       * @param expectedGotPart
77       *            the expected got part
78       */
79      private void assertMessage(String foundMessage, String expectedExpectedPart, String expectedGotPart) {
80  
81          var foundParts = foundMessage.split("(?=but:)");
82          assertEquals(2, foundParts.length, "split of foundMessage did not work: " + foundMessage);
83          var foundExpectedPart = foundParts[0].trim();
84          var foundGotPart = foundParts[1].trim();
85          assertEquals(expectedExpectedPart, foundExpectedPart);
86          assertEquals(expectedGotPart, foundGotPart);
87      }
88  
89      /**
90       * Matcher instance of.
91       */
92      @Test
93      void matcherInstanceOf() {
94  
95          assertThat(caughtThrowable(), instanceOf(IndexOutOfBoundsException.class));
96  
97          assertThat(caughtThrowable(), isA(Throwable.class));
98  
99          try {
100             assertThat(caughtThrowable(), instanceOf(IllegalArgumentException.class));
101             throw new RuntimeException("AssertionError expected");
102         } catch (AssertionError e) {
103             if (!e.getMessage().contains(expectedMessageJdk9on)) {
104                 assertMessage(e.getMessage(), "Expected: an instance of java.lang.IllegalArgumentException",
105                         "but: <java.lang.IndexOutOfBoundsException: Index: 9, Size: 9> is a java.lang"
106                                 + ".IndexOutOfBoundsException");
107             }
108         }
109     }
110 
111     /**
112      * Contains pattern.
113      *
114      * @param regex
115      *            the regex
116      *
117      * @return the org.hamcrest. matcher
118      */
119     private static org.hamcrest.Matcher<String> containsPattern(String regex) {
120         return new Find(regex);
121     }
122 
123     /**
124      * Learningtest matcher has message find regex.
125      */
126     @Test
127     void learningtestMatcher_hasMessage_findRegex() {
128 
129         if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
130             assertThat(caughtThrowable(), hasMessageThat(containsPattern("Index: \\d+")));
131         }
132 
133         try {
134             assertThat(caughtThrowable(), hasMessageThat(containsPattern("Index : \\d+")));
135             throw new RuntimeException("AssertionError expected");
136         } catch (AssertionError e) {
137             // OK
138         }
139     }
140 
141     /**
142      * Matcher has message equal by string.
143      */
144     @Test
145     void matcherHasMessageEqualByString() {
146 
147         if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
148             assertThat(caughtThrowable(), hasMessage("Index: 9, Size: 9"));
149         }
150 
151         try {
152             assertThat(caughtThrowable(), hasMessage("something went wrong"));
153             throw new RuntimeException("AssertionError expected");
154         } catch (AssertionError e) {
155             if (!e.getMessage().contains(expectedMessageJdk9on)) {
156                 assertMessage(e.getMessage(), "Expected: has a message that is \"something went wrong\"",
157                         "but: was <java.lang.IndexOutOfBoundsException: Index: 9, Size: 9>");
158             }
159         }
160     }
161 
162     /**
163      * Matcher has message equal by string matcher.
164      */
165     @Test
166     void matcherHasMessageEqualByStringMatcher() {
167 
168         if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
169             assertThat(caughtThrowable(), hasMessageThat(is("Index: 9, Size: 9")));
170         }
171 
172         try {
173             assertThat(caughtThrowable(), hasMessageThat(is("something went wrong")));
174             throw new RuntimeException("AssertionError expected");
175         } catch (AssertionError e) {
176             if (!e.getMessage().contains(expectedMessageJdk9on)) {
177                 assertMessage(e.getMessage(), "Expected: has a message that is \"something went wrong\"",
178                         "but: was <java.lang.IndexOutOfBoundsException: Index: 9, Size: 9>");
179             }
180         }
181     }
182 
183     /**
184      * Matcher has message contains by string matcher.
185      */
186     @Test
187     void matcherHasMessageContainsByStringMatcher() {
188 
189         if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
190             assertThat(caughtThrowable(), hasMessageThat(is(containsString("Index: 9"))));
191         }
192 
193         try {
194             assertThat(caughtThrowable(), hasMessageThat(is(containsString("Index: 8"))));
195             throw new RuntimeException("AssertionError expected");
196         } catch (AssertionError e) {
197             if (!e.getMessage().contains(expectedMessageJdk9on)) {
198                 assertMessage(e.getMessage(), "Expected: has a message that is a string containing \"Index: 8\"",
199                         "but: was <java.lang.IndexOutOfBoundsException: Index: 9, Size: 9>");
200             }
201         }
202     }
203 
204     /**
205      * Matcher has no cause.
206      */
207     @Test
208     void matcherHasNoCause() {
209 
210         assertThat(caughtThrowable(), hasNoCause());
211 
212         try {
213             assertThat(new RuntimeException(caughtThrowable()), hasNoCause());
214             throw new RuntimeException("AssertionError expected");
215         } catch (AssertionError e) {
216             if (!e.getMessage().contains(expectedMessageJdk9on)) {
217                 assertMessage(e.getMessage(), //
218                         "Expected: has no cause", "but: was <java.lang.RuntimeException: "
219                                 + "java.lang.IndexOutOfBoundsException:" + " Index: 9, Size: 9>");
220             }
221         }
222     }
223 
224     /**
225      * Matcher all of.
226      */
227     @Test
228     void matcherAllOf() {
229 
230         if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
231             assertThat(caughtThrowable(), allOf( //
232                     instanceOf(IndexOutOfBoundsException.class), //
233                     hasMessage("Index: 9, Size: 9"), //
234                     hasNoCause() //
235             ));
236         }
237 
238         try {
239             assertThat(caughtThrowable(), allOf( //
240                     instanceOf(IndexOutOfBoundsException.class), //
241                     hasMessage("something went wrong"), //
242                     hasNoCause() //
243             ));
244             throw new RuntimeException("AssertionError expected");
245         } catch (AssertionError e) {
246             if (!caughtThrowable().getMessage().contains(expectedMessageJdk9on)) {
247                 assertMessage(e.getMessage(), "Expected: " //
248                         + "(an instance of java.lang.IndexOutOfBoundsException" //
249                         + " and has a message that is \"something went wrong\"" //
250                         + " and has no cause)",
251                         "but: has a message that is \"something went wrong\" was <java.lang.IndexOutOfBoundsException: "
252                                 + "Index: 9, Size: 9>");
253             }
254         }
255 
256     }
257 
258 }