1/*
2 * Copyright 2001-2008 Artima, 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 */
16package org.scalatest.matchers
17
18import org.scalatest._
19import org.scalatest.prop.Checkers
20import org.scalacheck._
21import Arbitrary._
22import Prop._
23
24class ShouldEndWithSubstringSpec extends Spec with ShouldMatchers with Checkers with ReturnsNormallyThrowsAssertion {
25
26  describe("The endWith substring syntax") {
27
28    it("should do nothing if the string ends with the specified substring") {
29
30      "1.78" should endWith (".78")
31      "21.7" should endWith ("7")
32      "21.78" should endWith ("21.78")
33      check((s: String, t: String) => returnsNormally(s + t should endWith (t)))
34    }
35
36    it("should do nothing if the string does not end with the specified substring when used with not") {
37
38      "eight" should not { endWith ("1.7") }
39      "eight" should not endWith ("1.7")
40      check((s: String, t: String) => !(s + t).endsWith(s) ==> returnsNormally(s + t should not (endWith (s))))
41      check((s: String, t: String) => !(s + t).endsWith(s) ==> returnsNormally(s + t should not endWith (s)))
42    }
43
44    it("should do nothing if the string does not end with the specified substring when used in a logical-and expression") {
45
46      "1.7b" should ((endWith ("1.7b")) and (endWith ("7b")))
47      "1.7b" should (endWith ("1.7b") and (endWith ("7b")))
48      "1.7b" should (endWith ("1.7b") and endWith ("7b"))
49
50      check((s: String, t: String) => returnsNormally(s + t should (endWith (t) and endWith (""))))
51    }
52
53    it("should do nothing if the string does not end with the specified substring when used in a logical-or expression") {
54
55      "1.7b" should (endWith ("hello") or (endWith ("1.7b")))
56      "1.7b" should ((endWith ("hello")) or (endWith ("1.7b")))
57      "1.7b" should (endWith ("hello") or endWith ("1.7b"))
58
59      "1.7b" should (endWith ("hello") or (endWith ("7b")))
60      "1.7b" should ((endWith ("hello")) or (endWith ("7b")))
61      "1.7b" should (endWith ("hello") or endWith ("7b"))
62
63      check((s: String, t: String) => returnsNormally(s + t should (endWith ("hi") or endWith (t))))
64    }
65
66    it("should do nothing if the string does not end with the specified substring when used in a logical-and expression with not") {
67
68      "fred" should (not (endWith ("fre")) and not (endWith ("1.7")))
69      "fred" should ((not endWith ("fre")) and (not endWith ("1.7")))
70      "fred" should (not endWith ("fre") and not endWith ("1.7"))
71      check((s: String) => !(s endsWith "bob") && !(s endsWith "1.7") ==> returnsNormally(s should (not endWith ("bob") and not endWith ("1.7"))))
72    }
73
74    it("should do nothing if the string does not end with the specified substring when used in a logical-or expression with not") {
75      "fred" should (not (endWith ("fred")) or not (endWith ("1.7")))
76      "fred" should ((not endWith ("fred")) or (not endWith ("1.7")))
77      "fred" should (not endWith ("fred") or not endWith ("1.7"))
78      check((s: String) => s.indexOf("a") != 0 || s.indexOf("b") != 0 ==> returnsNormally(s should (not endWith ("a") or not endWith ("b"))))
79    }
80
81    it("should throw TestFailedException if the string does not match the specified substring") {
82
83      val caught1 = intercept[TestFailedException] {
84        "1.7" should endWith ("1.78")
85      }
86      assert(caught1.getMessage === "\"1.7\" did not end with substring \"1.78\"")
87
88      val caught2 = intercept[TestFailedException] {
89        "1.7" should endWith ("21.7")
90      }
91      assert(caught2.getMessage === "\"1.7\" did not end with substring \"21.7\"")
92
93      val caught3 = intercept[TestFailedException] {
94        "1.78" should endWith ("1.7")
95      }
96      assert(caught3.getMessage === "\"1.78\" did not end with substring \"1.7\"")
97
98      val caught6 = intercept[TestFailedException] {
99        "eight" should endWith ("1.7")
100      }
101      assert(caught6.getMessage === "\"eight\" did not end with substring \"1.7\"")
102
103      val caught7 = intercept[TestFailedException] {
104        "one.eight" should endWith ("1.7")
105      }
106      assert(caught7.getMessage === "\"one.eight\" did not end with substring \"1.7\"")
107
108      val caught8 = intercept[TestFailedException] {
109        "onedoteight" should endWith ("1.7")
110      }
111      assert(caught8.getMessage === "\"onedoteight\" did not end with substring \"1.7\"")
112
113      val caught9 = intercept[TestFailedException] {
114        "***" should endWith ("1.7")
115      }
116      assert(caught9.getMessage === "\"***\" did not end with substring \"1.7\"")
117
118      check((s: String) => !(s endsWith "1.7") ==> throwsTestFailedException(s should endWith ("1.7")))
119    }
120
121    it("should throw TestFailedException if the string does matches the specified substring when used with not") {
122
123      val caught1 = intercept[TestFailedException] {
124        "1.7" should not { endWith ("1.7") }
125      }
126      assert(caught1.getMessage === "\"1.7\" ended with substring \"1.7\"")
127
128      val caught2 = intercept[TestFailedException] {
129        "1.7" should not { endWith ("7") }
130      }
131      assert(caught2.getMessage === "\"1.7\" ended with substring \"7\"")
132
133      val caught3 = intercept[TestFailedException] {
134        "-1.8" should not { endWith (".8") }
135      }
136      assert(caught3.getMessage === "\"-1.8\" ended with substring \".8\"")
137
138      val caught4 = intercept[TestFailedException] {
139        "8b" should not { endWith ("b") }
140      }
141      assert(caught4.getMessage === "\"8b\" ended with substring \"b\"")
142
143      val caught5 = intercept[TestFailedException] {
144        "1." should not { endWith ("1.") }
145      }
146      assert(caught5.getMessage === "\"1.\" ended with substring \"1.\"")
147
148      val caught11 = intercept[TestFailedException] {
149        "1.7" should not endWith (".7")
150      }
151      assert(caught11.getMessage === "\"1.7\" ended with substring \".7\"")
152
153      val caught13 = intercept[TestFailedException] {
154        "-1.8" should not endWith ("8")
155      }
156      assert(caught13.getMessage === "\"-1.8\" ended with substring \"8\"")
157
158      val caught14 = intercept[TestFailedException] {
159        "8" should not endWith ("")
160      }
161      assert(caught14.getMessage === "\"8\" ended with substring \"\"")
162
163      val caught15 = intercept[TestFailedException] {
164        "1." should not endWith ("1.")
165      }
166      assert(caught15.getMessage === "\"1.\" ended with substring \"1.\"")
167
168      val caught21 = intercept[TestFailedException] {
169        "1.7a" should not { endWith ("7a") }
170      }
171      assert(caught21.getMessage === "\"1.7a\" ended with substring \"7a\"")
172
173      val caught22 = intercept[TestFailedException] {
174        "b1.7" should not { endWith ("1.7") }
175      }
176      assert(caught22.getMessage === "\"b1.7\" ended with substring \"1.7\"")
177
178      val caught23 = intercept[TestFailedException] {
179        "ba-1.8" should not { endWith ("a-1.8") }
180      }
181      assert(caught23.getMessage === "\"ba-1.8\" ended with substring \"a-1.8\"")
182
183      check((s: String) => s.length != 0 ==> throwsTestFailedException(s should not endWith (s.substring(s.length - 1, s.length))))
184    }
185
186    it("should throw TestFailedException if the string ends with the specified substring when used in a logical-and expression") {
187
188      val caught1 = intercept[TestFailedException] {
189        "1.7" should (endWith ("1.7") and (endWith ("1.8")))
190      }
191      assert(caught1.getMessage === "\"1.7\" ended with substring \"1.7\", but \"1.7\" did not end with substring \"1.8\"")
192
193      val caught2 = intercept[TestFailedException] {
194        "1.7" should ((endWith ("7")) and (endWith ("1.8")))
195      }
196      assert(caught2.getMessage === "\"1.7\" ended with substring \"7\", but \"1.7\" did not end with substring \"1.8\"")
197
198      val caught3 = intercept[TestFailedException] {
199        "1.7" should (endWith (".7") and endWith ("1.8"))
200      }
201      assert(caught3.getMessage === "\"1.7\" ended with substring \".7\", but \"1.7\" did not end with substring \"1.8\"")
202
203      // Check to make sure the error message "short circuits" (i.e., just reports the left side's failure)
204      val caught4 = intercept[TestFailedException] {
205        "one.eight" should (endWith ("1.7") and (endWith ("1.8")))
206      }
207      assert(caught4.getMessage === "\"one.eight\" did not end with substring \"1.7\"")
208
209      val caught5 = intercept[TestFailedException] {
210        "one.eight" should ((endWith ("1.7")) and (endWith ("1.8")))
211      }
212      assert(caught5.getMessage === "\"one.eight\" did not end with substring \"1.7\"")
213
214      val caught6 = intercept[TestFailedException] {
215        "one.eight" should (endWith ("1.7") and endWith ("1.8"))
216      }
217      assert(caught6.getMessage === "\"one.eight\" did not end with substring \"1.7\"")
218
219      check((s: String, t: String, u: String) => !((s + u) endsWith t) ==> throwsTestFailedException(s + u should (endWith (u) and endWith (t))))
220    }
221
222    it("should throw TestFailedException if the string ends with the specified substring when used in a logical-or expression") {
223
224      val caught1 = intercept[TestFailedException] {
225        "one.seven" should (endWith ("1.7") or (endWith ("1.8")))
226      }
227      assert(caught1.getMessage === "\"one.seven\" did not end with substring \"1.7\", and \"one.seven\" did not end with substring \"1.8\"")
228
229      val caught2 = intercept[TestFailedException] {
230        "one.seven" should ((endWith ("1.7")) or (endWith ("1.8")))
231      }
232      assert(caught2.getMessage === "\"one.seven\" did not end with substring \"1.7\", and \"one.seven\" did not end with substring \"1.8\"")
233
234      val caught3 = intercept[TestFailedException] {
235        "one.seven" should (endWith ("1.7") or endWith ("1.8"))
236      }
237      assert(caught3.getMessage === "\"one.seven\" did not end with substring \"1.7\", and \"one.seven\" did not end with substring \"1.8\"")
238
239      check(
240        (s: String, t: String, u: String, v: String) => {
241          (t.length != 0 && v.length != 0 && !(s + u).endsWith(t) && !(s + u).endsWith(v)) ==>
242            throwsTestFailedException(s + u should (endWith (t) or endWith (v)))
243        }
244      )
245    }
246
247    it("should throw TestFailedException if the string ends with the specified substring when used in a logical-and expression used with not") {
248
249      val caught1 = intercept[TestFailedException] {
250        "1.7" should (not endWith ("1.8") and (not endWith ("1.7")))
251      }
252      assert(caught1.getMessage === "\"1.7\" did not end with substring \"1.8\", but \"1.7\" ended with substring \"1.7\"")
253
254      val caught2 = intercept[TestFailedException] {
255        "1.7" should ((not endWith ("1.8")) and (not endWith ("1.7")))
256      }
257      assert(caught2.getMessage === "\"1.7\" did not end with substring \"1.8\", but \"1.7\" ended with substring \"1.7\"")
258
259      val caught3 = intercept[TestFailedException] {
260        "1.7" should (not endWith ("1.8") and not endWith ("1.7"))
261      }
262      assert(caught3.getMessage === "\"1.7\" did not end with substring \"1.8\", but \"1.7\" ended with substring \"1.7\"")
263
264      val caught4 = intercept[TestFailedException] {
265        "a1.7" should (not endWith ("1.8") and (not endWith ("a1.7")))
266      }
267      assert(caught4.getMessage === "\"a1.7\" did not end with substring \"1.8\", but \"a1.7\" ended with substring \"a1.7\"")
268
269      val caught5 = intercept[TestFailedException] {
270        "b1.7" should ((not endWith ("1.8")) and (not endWith ("1.7")))
271      }
272      assert(caught5.getMessage === "\"b1.7\" did not end with substring \"1.8\", but \"b1.7\" ended with substring \"1.7\"")
273
274      val caught6 = intercept[TestFailedException] {
275        "a1.7b" should (not endWith ("1.8") and not endWith ("1.7b"))
276      }
277      assert(caught6.getMessage === "\"a1.7b\" did not end with substring \"1.8\", but \"a1.7b\" ended with substring \"1.7b\"")
278
279      check(
280        (s: String, t: String, u: String) =>
281          (s + t + u).indexOf("hi") != 0 ==>
282            throwsTestFailedException(s + t + u should (not endWith ("hi") and not endWith (u)))
283      )
284    }
285
286    it("should throw TestFailedException if the string ends with the specified substring when used in a logical-or expression used with not") {
287
288      val caught1 = intercept[TestFailedException] {
289        "1.7" should (not endWith ("1.7") or (not endWith ("1.7")))
290      }
291      assert(caught1.getMessage === "\"1.7\" ended with substring \"1.7\", and \"1.7\" ended with substring \"1.7\"")
292
293      val caught2 = intercept[TestFailedException] {
294        "1.7" should ((not endWith ("1.7")) or (not endWith ("1.7")))
295      }
296      assert(caught2.getMessage === "\"1.7\" ended with substring \"1.7\", and \"1.7\" ended with substring \"1.7\"")
297
298      val caught3 = intercept[TestFailedException] {
299        "1.7" should (not endWith ("1.7") or not endWith ("1.7"))
300      }
301      assert(caught3.getMessage === "\"1.7\" ended with substring \"1.7\", and \"1.7\" ended with substring \"1.7\"")
302
303      val caught4 = intercept[TestFailedException] {
304        "1.7" should (not (endWith ("1.7")) or not (endWith ("1.7")))
305      }
306      assert(caught4.getMessage === "\"1.7\" ended with substring \"1.7\", and \"1.7\" ended with substring \"1.7\"")
307
308      val caught5 = intercept[TestFailedException] {
309        "a1.7" should (not endWith (".7") or (not endWith ("a1.7")))
310      }
311      assert(caught5.getMessage === "\"a1.7\" ended with substring \".7\", and \"a1.7\" ended with substring \"a1.7\"")
312
313      val caught6 = intercept[TestFailedException] {
314        "b1.7" should ((not endWith ("1.7")) or (not endWith ("1.7")))
315      }
316      assert(caught6.getMessage === "\"b1.7\" ended with substring \"1.7\", and \"b1.7\" ended with substring \"1.7\"")
317
318      val caught7 = intercept[TestFailedException] {
319        "a1.7b" should (not endWith ("1.7b") or not endWith ("7b"))
320      }
321      assert(caught7.getMessage === "\"a1.7b\" ended with substring \"1.7b\", and \"a1.7b\" ended with substring \"7b\"")
322
323      val caught8 = intercept[TestFailedException] {
324        "a1.7b" should (not (endWith ("1.7b")) or not (endWith ("7b")))
325      }
326      assert(caught8.getMessage === "\"a1.7b\" ended with substring \"1.7b\", and \"a1.7b\" ended with substring \"7b\"")
327
328      check(
329        (s: String, t: String) =>
330          throwsTestFailedException(s + t should (not endWith (t) or not endWith ("")))
331      )
332    }
333  }
334}
335
336