001 /*
002 * Created on Nov 18, 2010
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005 * the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 *
013 * Copyright @2010-2011 the original author or authors.
014 */
015 package org.fest.assertions.api;
016
017 import java.util.Collection;
018 import java.util.Comparator;
019
020 import org.fest.assertions.core.Assert;
021 import org.fest.assertions.core.Condition;
022 import org.fest.assertions.core.WritableAssertionInfo;
023 import org.fest.assertions.description.Description;
024 import org.fest.assertions.internal.Conditions;
025 import org.fest.assertions.internal.Objects;
026 import org.fest.util.ComparatorBasedComparisonStrategy;
027 import org.fest.util.VisibleForTesting;
028
029
030 /**
031 * Base class for all assertions.
032 * @param <S> the "self" type of this assertion class. Please read "<a href="http://bit.ly/anMa4g"
033 * target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>"
034 * for more details.
035 * @param <A> the type of the "actual" value.
036 *
037 * @author Alex Ruiz
038 * @author Joel Costigliola
039 */
040 public abstract class AbstractAssert<S, A> implements Assert<S, A> {
041
042 @VisibleForTesting
043 Objects objects = Objects.instance();
044
045 @VisibleForTesting
046 Conditions conditions = Conditions.instance();
047
048 @VisibleForTesting
049 final WritableAssertionInfo info;
050
051 // visibility is protected to allow us write custom assertions that need access to actual
052 @VisibleForTesting
053 protected final A actual;
054 protected final S myself;
055
056 protected AbstractAssert(A actual, Class<S> selfType) {
057 myself = selfType.cast(this);
058 this.actual = actual;
059 info = new WritableAssertionInfo();
060 }
061
062 /** {@inheritDoc} */
063 public final S as(String description) {
064 return describedAs(description);
065 }
066
067 /** {@inheritDoc} */
068 public final S as(Description description) {
069 return describedAs(description);
070 }
071
072 /** {@inheritDoc} */
073 public final S describedAs(String description) {
074 info.description(description);
075 return myself;
076 }
077
078 /** {@inheritDoc} */
079 public final S describedAs(Description description) {
080 info.description(description);
081 return myself;
082 }
083
084 /** {@inheritDoc} */
085 public S isEqualTo(A expected) {
086 objects.assertEqual(info, actual, expected);
087 return myself;
088 }
089
090 /** {@inheritDoc} */
091 public S isNotEqualTo(A other) {
092 objects.assertNotEqual(info, actual, other);
093 return myself;
094 }
095
096 /** {@inheritDoc} */
097 public final void isNull() {
098 objects.assertNull(info, actual);
099 }
100
101 /** {@inheritDoc} */
102 public final S isNotNull() {
103 objects.assertNotNull(info, actual);
104 return myself;
105 }
106
107 /** {@inheritDoc} */
108 public final S isSameAs(A expected) {
109 objects.assertSame(info, actual, expected);
110 return myself;
111 }
112
113 /** {@inheritDoc} */
114 public final S isNotSameAs(A other) {
115 objects.assertNotSame(info, actual, other);
116 return myself;
117 }
118
119 /** {@inheritDoc} */
120 public final S isIn(A... values) {
121 objects.assertIsIn(info, actual, values);
122 return myself;
123 }
124
125 /** {@inheritDoc} */
126 public final S isNotIn(A... values) {
127 objects.assertIsNotIn(info, actual, values);
128 return myself;
129 }
130
131 /** {@inheritDoc} */
132 public final S isIn(Collection<?> values) {
133 objects.assertIsIn(info, actual, values);
134 return myself;
135 }
136
137 /** {@inheritDoc} */
138 public final S isNotIn(Collection<?> values) {
139 objects.assertIsNotIn(info, actual, values);
140 return myself;
141 }
142
143 /** {@inheritDoc} */
144 public final S is(Condition<A> condition) {
145 conditions.assertIs(info, actual, condition);
146 return myself;
147 }
148
149 /** {@inheritDoc} */
150 public final S isNot(Condition<A> condition) {
151 conditions.assertIsNot(info, actual, condition);
152 return myself;
153 }
154
155 /** {@inheritDoc} */
156 public final S has(Condition<A> condition) {
157 conditions.assertHas(info, actual, condition);
158 return myself;
159 }
160
161 /** {@inheritDoc} */
162 public final S doesNotHave(Condition<A> condition) {
163 conditions.assertDoesNotHave(info, actual, condition);
164 return myself;
165 }
166
167 /**
168 * The description of this assertion set with {@link #describedAs(String)} or {@link #describedAs(Description)}.
169 * @return the description String representation of this assertion.
170 */
171 public final String descriptionText() {
172 return info.descriptionText();
173 }
174
175 /** {@inheritDoc} */
176 public S usingComparator(Comparator<?> customComparator) {
177 // using a specific strategy to compare actual with other objects.
178 this.objects = new Objects(new ComparatorBasedComparisonStrategy(customComparator));
179 return myself;
180 }
181
182 /** {@inheritDoc} */
183 public S usingDefaultComparator() {
184 // fall back to default strategy to compare actual with other objects.
185 this.objects = Objects.instance();
186 return myself;
187 }
188
189 /** {@inheritDoc} */
190 @Override
191 public final boolean equals(Object obj) {
192 throw new UnsupportedOperationException("'equals' is not supported...maybe you intended to call 'isEqualTo'");
193 }
194
195 /**
196 * Always returns 1.
197 * @return 1.
198 */
199 @Override
200 public final int hashCode() {
201 return 1;
202 }
203
204 }