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 ShouldEqualSpec extends Spec with ShouldMatchers with Checkers with ReturnsNormallyThrowsAssertion {
25
26  // Checking for equality with "equal"
27  describe("The equal token") {
28
29    it("should do nothing when equal") {
30      1 should equal (1)
31
32      // objects should equal themselves
33      check((s: String) => returnsNormally(s should equal (s)))
34      check((i: Int) => returnsNormally(i should equal (i)))
35
36      // a string should equal another string with the same value
37      check((s: String) => returnsNormally(s should equal (new String(s))))
38    }
39
40    it("should do nothing when not equal and used with not") {
41      1 should not { equal (2) }
42      1 should not equal (2)
43
44      // unequal objects should not equal each other
45      check((s: String, t: String) => s != t ==> returnsNormally(s should not { equal (t) }))
46      check((s: String, t: String) => s != t ==> returnsNormally(s should not equal (t)))
47    }
48
49    it("should do nothing when equal and used in a logical-and expression") {
50      1 should (equal (1) and equal (2 - 1))
51    }
52
53    it("should do nothing when equal and used in multi-part logical expressions") {
54
55        // Just to make sure these work strung together
56        1 should (equal (1) and equal (1) and equal (1) and equal (1))
57        1 should (equal (1) and equal (1) or equal (1) and equal (1) or equal (1))
58        1 should (
59            equal (1) and
60            equal (1) or
61            equal (1) and
62            equal (1) or
63            equal (1)
64        )
65    }
66
67    it("should do nothing when equal and used in a logical-or expression") {
68      1 should { equal (1) or equal (2 - 1) }
69    }
70
71    it("should do nothing when not equal and used in a logical-and expression with not") {
72      1 should { not { equal (2) } and not { equal (3 - 1) }}
73      1 should { not equal (2) and (not equal (3 - 1)) }
74      1 should (not equal (2) and not equal (3 - 1))
75    }
76
77    it("should do nothing when not equal and used in a logical-or expression with not") {
78      1 should { not { equal (2) } or not { equal (3 - 1) }}
79      1 should { not equal (2) or (not equal (3 - 1)) }
80      1 should (not equal (2) or not equal (3 - 1))
81    }
82
83    it("should throw an assertion error when not equal") {
84      val caught1 = intercept[TestFailedException] {
85        1 should equal (2)
86      }
87      assert(caught1.getMessage === "1 did not equal 2")
88
89      // unequal objects used with "a should equal (b)" should throw an TestFailedException
90      check((s: String, t: String) => s != t ==> throwsTestFailedException(s should equal (t)))
91
92      val caught2 = intercept[TestFailedException] {
93        1 should not (not equal (2))
94      }
95      assert(caught2.getMessage === "1 did not equal 2")
96    }
97
98    it("should throw an assertion error when equal but used with should not") {
99      val caught1 = intercept[TestFailedException] {
100        1 should not { equal (1) }
101      }
102      assert(caught1.getMessage === "1 equaled 1")
103
104      val caught2 = intercept[TestFailedException] {
105        1 should not equal (1)
106      }
107      assert(caught2.getMessage === "1 equaled 1")
108
109      // the same object used with "a should not { equal (a) } should throw TestFailedException
110      check((s: String) => throwsTestFailedException(s should not { equal (s) }))
111      check((i: Int) => throwsTestFailedException(i should not { equal (i) }))
112      check((s: String) => throwsTestFailedException(s should not equal (s)))
113      check((i: Int) => throwsTestFailedException(i should not equal (i)))
114
115      // two different strings with the same value used with "s should not { equal (t) } should throw TestFailedException
116      check((s: String) => throwsTestFailedException(s should not { equal (new String(s)) }))
117      check((s: String) => throwsTestFailedException(s should not equal (new String(s))))
118
119      val caught3 = intercept[TestFailedException] {
120        1 should not (not (not equal (1)))
121      }
122      assert(caught3.getMessage === "1 equaled 1")
123    }
124
125    it("should throw an assertion error when not equal and used in a logical-and expression") {
126      val caught = intercept[TestFailedException] {
127        1 should { equal (5) and equal (2 - 1) }
128      }
129      assert(caught.getMessage === "1 did not equal 5")
130    }
131
132    it("should throw an assertion error when not equal and used in a logical-or expression") {
133      val caught = intercept[TestFailedException] {
134        1 should { equal (5) or equal (5 - 1) }
135      }
136      assert(caught.getMessage === "1 did not equal 5, and 1 did not equal 4")
137    }
138
139    it("should throw an assertion error when equal and used in a logical-and expression with not") {
140
141      val caught1 = intercept[TestFailedException] {
142        1 should { not { equal (1) } and not { equal (3 - 1) }}
143      }
144      assert(caught1.getMessage === "1 equaled 1")
145
146      val caught2 = intercept[TestFailedException] {
147        1 should { not equal (1) and (not equal (3 - 1)) }
148      }
149      assert(caught2.getMessage === "1 equaled 1")
150
151      val caught3 = intercept[TestFailedException] {
152        1 should (not equal (1) and not equal (3 - 1))
153      }
154      assert(caught3.getMessage === "1 equaled 1")
155
156      val caught4 = intercept[TestFailedException] {
157        1 should { not { equal (2) } and not { equal (1) }}
158      }
159      assert(caught4.getMessage === "1 did not equal 2, but 1 equaled 1")
160
161      val caught5 = intercept[TestFailedException] {
162        1 should { not equal (2) and (not equal (1)) }
163      }
164      assert(caught5.getMessage === "1 did not equal 2, but 1 equaled 1")
165
166      val caught6 = intercept[TestFailedException] {
167        1 should (not equal (2) and not equal (1))
168      }
169      assert(caught6.getMessage === "1 did not equal 2, but 1 equaled 1")
170    }
171
172    it("should throw an assertion error when equal and used in a logical-or expression with not") {
173
174      val caught1 = intercept[TestFailedException] {
175        1 should { not { equal (1) } or not { equal (2 - 1) }}
176      }
177      assert(caught1.getMessage === "1 equaled 1, and 1 equaled 1")
178
179      val caught2 = intercept[TestFailedException] {
180        1 should { not equal (1) or { not equal (2 - 1) }}
181      }
182      assert(caught2.getMessage === "1 equaled 1, and 1 equaled 1")
183
184      val caught3 = intercept[TestFailedException] {
185        1 should (not equal (1) or not equal (2 - 1))
186      }
187      assert(caught3.getMessage === "1 equaled 1, and 1 equaled 1")
188    }
189  }
190}
191